@Override
Public class example {
void test {
try {
someMethod(); //This throws TimeoutException
} catch (TimeoutException ex) {
throw new TimeoutException(ex); //It doesn't throw error if I replace this with throw new RuntimeException(ex)
} }
}
上面的例子给出了一个错误'throw new TimeoutException(ex)',因为java.util.concurrent.TimeoutException中的“TimeoutException(java.lang.string)”不能应用于(java.util.concurrent.TimeoutException)“
但如果我用'throw new RuntimeException(ex)'替换它,它不会抛出错误;
答案 0 :(得分:1)
TimeoutException
没有一个构造函数接受TimeoutException
作为TimeoutException(TimeoutException cause)
或类似形式的参数。
您可以改为:
TimeoutException localtoe=new TimeoutException("test failed");
localtoe.initCause(ex);
throw localtoe;
或同样地:
throw new TimeoutException("test failed").initCause(ex);
initCause()
只能调用一次,并且只有在构造函数未设置cause时才会调用。这是一个有趣的小方法,就像构思后的思想(*)。
将异常包装为异常原因并没有什么不妥。
假设testFunction()
连接然后执行某些操作。
您可能希望抛出一个异常,消息“testFunction中的连接失败”,另一个“testFunction中的操作失败”,具体取决于哪个子步骤失败。
但是如果你不需要提供如此多的细节,你可以throw ex
或者让这个方法放松,而不会自己捕捉任何东西。
这是一个小例子:
import java.util.concurrent.TimeoutException;
class Example{
private static void connect() throws TimeoutException {
//Dummy connection that just fails...
throw new TimeoutException("connection failed");
}
private static void process() throws TimeoutException {
try {
connect();
}catch(TimeoutException toe){
TimeoutException toeout=new TimeoutException("process failed because connection failed.");
toeout.initCause(toe);
throw toeout;
}
//Code for when connection succeeds...
}
public static void main (String[] args) throws java.lang.Exception
{
try{
process();
}catch(TimeoutException toe){
System.out.println(toe);
}
}
}
预期产出:
java.util.concurrent.TimeoutException: process failed because connection failed.
(*)initCause()
看起来像是一个经过深思熟虑的,有点像。它于2002年被添加到Java 1.4中。该文档讨论了“遗留”构造函数。它不是将构造数量增加一倍(添加一个Throwable cause
参数),而是决定允许它作为bolt-on初始化。
这是否是最好的解决方案值得商榷。
答案 1 :(得分:0)
这里有三个选项:
TimeoutException
并丢失堆栈跟踪:throw new TimeoutException(ex.getMessage());
RuntimeException
。您决定,每个选项都有优点和缺点。
更新(感谢@Mark Rottenveel)
可以重写第2点:throw new TimeoutException(ex.getMessage()).initCause(ex);
以保持指向原始异常的链接。
答案 2 :(得分:0)
我在你的问题中观察到的事情
您正尝试直接从try缓存块中的类调用方法。你必须创建方法并从那个
你想抛出异常。所以你必须从你调用它的地方扔掉它的方法级别
请在下面找到演示解决方案:
public class example {
public void testFunction() throws TimeoutException {
try {
someFunction();
} catch (TimeoutException ex) {
throw ex;
}
}
public void someFunction() throws TimeoutException {
}
}
答案 3 :(得分:0)
Java有两类例外:已选中和未选中。必须在函数签名中声明已检查的异常(通常是Exception
的子类),而未经检查的异常(通常是RuntimeException
的子类)则不能。
TimeoutException
是一个经过检查的例外。当它可以从一个没有声明它的方法抛出时,你有两个选择:
在签名中声明:
public void func1() throws TimeoutException {
somefunction();
}
干净简单,但它可能有问题是func1是一个未声明为抛出此异常的函数的覆盖,它是从另一个函数(假设来自框架)调用的,它不会声明它
在未经检查的异常中隐藏
public void func1() {
try {
somefunction();
} catch (TimeoutException e) {
throw new RuntimeException(e);
}
}
你丢失了声明部分(由于这个原因存在已检查的异常),但至少它允许你从不声明它的函数中调用它。