Java 我不能抛出特定的异常吗
上面的示例给出了一个错误“throw new TimeoutException(ex)”和“java.util.concurrent.TimeoutException中的TimeoutException(java.lang.string)不能应用于(java.util.concurrent.TimeoutException)”Java 我不能抛出特定的异常吗,java,Java,上面的示例给出了一个错误“throw new TimeoutException(ex)”和“java.util.concurrent.TimeoutException中的TimeoutException(java.lang.string)不能应用于(java.util.concurrent.TimeoutException)” 但如果我将其替换为“throw new RuntimeException(ex)”,它不会抛出错误 这里大致有三个选项: 重新抛出相同的异常:`throw ex;' 抛出
但如果我将其替换为“throw new RuntimeException(ex)”,它不会抛出错误 这里大致有三个选项:
TimeoutException
并丢失堆栈跟踪:抛出新的TimeoutException(例如getMessage())代码>
RuntimeException
第2点可以重写:
抛出新的TimeoutException(例如getMessage()).initCause(例如)
保留原始异常的链接。我在您的问题中观察到的情况
@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)
} }
}
Java有两类异常:已检查和未检查。选中的异常(通常是
异常的子类
)必须在函数签名中声明,而未选中的异常(通常是运行时异常的子类
)不能声明
TimeoutException
是一个选中的异常。当它可以从未声明它的方法中抛出时,您有2个选项:
- 在签名中声明:
干净简单但可能有问题的是func1是一个未声明的函数的重写以引发此异常,它是从另一个也未声明它的函数(假设来自框架)调用的public class example { public void testFunction() throws TimeoutException { try { someFunction(); } catch (TimeoutException ex) { throw ex; } } public void someFunction() throws TimeoutException { } }
- 将其隐藏在未检查的异常中
您将丢失声明性部分(由于该原因存在选中的异常),但至少它允许您从未声明声明声明的函数调用它public void func1() throws TimeoutException { somefunction(); }
TimeoutException
没有接受TimeoutException
作为形式为TimeoutException(TimeoutException原因)
或类似参数的构造函数
您可以改为:
public void func1() {
try {
somefunction();
} catch (TimeoutException e) {
throw new RuntimeException(e);
}
}
或者同等地:
TimeoutException localtoe=new TimeoutException("test failed");
localtoe.initCause(ex);
throw localtoe;
initCause()。这是一个有趣的小方法,它的行为就像一个经过思考的构造函数(*)
将异常包装为异常的原因并不一定是错误的。
假设testFunction()
连接,然后执行一些操作。
根据失败的子步骤,您可能希望抛出一个异常消息“testFunction中的连接失败”和另一个“testFunction中的操作失败”
但是,如果不需要提供太多细节,您可以抛出ex
,或者让方法在不捕获任何内容的情况下展开
这里有一个小例子:
throw new TimeoutException("test failed").initCause(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);
}
}
}
(*)initCause()。2002年,它被添加到Java1.4中。文档讨论了“遗留”构造函数。与其将构造函数的数量增加一倍(添加一个带有可丢弃原因
参数的构造函数),不如决定将其作为螺栓连接初始化。
这是否是最好的解决方案还存在争议。java.util.concurrent.TimeoutException没有接受其他异常的构造函数您想在TimeoutException
中打包TimeoutException
。你需要做的是抛出ex
由于这已经是您想要抛出的确切异常,TimeoutException
没有这样的构造函数:@XtremeBaumer,或者根本就没有捕获它。throw ex;说“未处理的异常”时出错。来自AndyTurner:或只是不首先捕获它
(向方法签名添加抛出
)@XtremeBaumer fair Enough前两个选项给出一个错误,说“未处理的异常”。@KishoreKumar yes,这是因为您没有像方法中抛出的那样声明TimeoutException
。您知道initCause(Throwable)
方法的存在吗?这意味着使用选项2,您也不会丢失堆栈跟踪。无需捕获异常并重新抛出它。您可以完全摆脱try/catch
。这样的做法意味着您需要多次记录异常。您通常只记录处理异常的位置,而不是在其中的步骤中。您可能需要考虑不要在另一个<代码> TimeOutExtExabor /代码>中包装“<代码> TimeOutExist< /代码>,因为这不太有意义。这也将简化过程()
,因为您可以完全取消try-catch。@markrottveel。我建议这样做,并同意将异常包装起来可能有些过分。但我讨厌那些只告诉人们不要做某事而不告诉他们如何做的答案。正如我在回答中所说,您可能有一个方法,该方法有多个步骤,每个步骤都可能超时,并指示哪些步骤失败。连接超时可能与某些操作的环境原因不同。仍然认为这有点过分了,但是没有一个其他的答案提到了initCause()
,如果你真的觉得需要的话,这就是如何做到的。
java.util.concurrent.TimeoutException: process failed because connection failed.