我想以不同的方式处理两种不同类型的异常,然后对两种异常类型进行相同的操作。如何用Java做到这一点?
以下代码显示了我想要做的事情,但它不正确,因为一个例外无法捕获两次。
这个的正确语法是什么?
try {
// do something...
}
catch (ExceptionA e) {
// actions for ExceptionA
}
catch (ExceptionB e) {
// actions for ExceptionB
}
catch (ExceptionA | ExceptionB e) {
// actions for ExceptionA & ExceptionB
}
答案 0 :(得分:6)
使用catch (ExceptionA | ExceptionB e)
构造。在catch
块中,首先对instanceof
执行e
检查,然后单独处理异常类型。在此之后,对这两种类型进行常规处理。这样您就可以在一个catch
块中执行所有操作:
try {
// do something...
} catch (ExceptionA | ExceptionB e) {
if (e instanceof ExceptionA) {
// handling for ExceptionA
} else {
// handling for ExceptionB
}
// common handling for both exception types
}
答案 1 :(得分:3)
使用公共代码的方法。
try {
// do something...
}
catch (ExceptionA e) {
// actions for ExceptionA
doCommon(parameters);
}
catch (ExceptionB e) {
// actions for ExceptionA
doCommon(parameters);
}
.....
void doCommon( parameters ) {
// actions for ExceptionA & ExceptionB
}
这对大多数事情都有效
虽然有一些例外,例如return
。为此,您可以让doCommon
返回,然后调用者必须返回,并将其用作:
catch (ExceptionA e) {
// actions for ExceptionA
if ( doCommon(parameters) )
return;
}
catch (ExceptionB e) {
// actions for ExceptionA
if ( doCommon(parameters) )
return;
}
“本机Java”解决方案不存在。 JLS指定(强调我的):
14.20.1。执行try-catch
首先执行没有finally块的try语句 试块。然后有一个选择:
如果try块的执行正常完成,则不再进一步 采取行动,并且try语句正常完成。
如果由于抛出而导致try块的执行突然完成 值V,然后有一个选择:
如果V的运行时类型与(第5.2节)a分配兼容 try语句的任何catch子句的可捕获异常类, 然后选择第一个(最左边)这样的catch子句。值V 被分配给所选catch子句的参数,以及 执行该catch子句的块,然后有一个选择:
如果该块正常完成,则try语句完成 通常
如果该块因任何原因突然完成,则尝试 由于同样的原因,声明突然完成。
如果V的运行时类型与a的分配不兼容 try语句的任何catch子句的可捕获异常类, 然后try语句突然完成,因为抛出了 价值V。
因此只执行适用的第一个catch块。没有办法为同一个try语句执行两个catch块。
答案 2 :(得分:1)
如果您正在寻找(ExceptionA | ExceptionB)
,您将能够捕获并处理相同的操作,只需要一个失败。对于多个Exception
条件,这基本上只是 new(1.7)的简写。
没有catch(ExceptionA && ExceptionB)
这样的东西。
例如:
readFile {
try {
open the file;
determine its size;
determine its content;
} catch (fileOpenFailed) {
doSomething;
} catch (sizeDeterminationFailed) {
doSomething;
} catch (contentDeterminationFailed) {
doSomething;
}
}
如果您希望将contentDeterminationFailed
和sizeDeterminationFailed
作为单个exception
捕获,那么您可能希望创建自己的自定义exception
类型,该类型可以唯一处理。
答案 3 :(得分:1)
此类型的解决方案是否适合您:
try {
// do something...
} catch (ExceptionA | ExceptionB e) {
// common code to be called for both...
// ....
handleException(e)
}
//....
void handleException(ExceptionA e) {
// code for A
}
//....
void handleException(ExceptionB e) {
// code for B
}
首先,您要对这两个问题执行常见操作,然后在适当的方法中为每个例外提供公共代码。这样您就不需要使用 instanceof 或 ifs 。
仅通过使用java构造来实现它的另一种方法是通过输入finally:
boolean fail = false;
try {
// your code
} catch (ExceptionA a) {
// exceptionA specific handling
fail = true;
} catch (ExceptionB b) {
// exceptionB specific handling
fail = true;
} finally {
if (fail) {
// common handling
}
}
答案 4 :(得分:0)
您可以重新抛出异常并再次处理:
try {
try {
// do something
} catch( ExceptionA e) {
// actions for ExceptionA
throw e;
} catch( ExceptionB e) {
// actions for ExceptionB
throw e;
}
} catch( ExceptionA | ExceptionB e) {
// Actions for exceptions A or B
}
也许,为了清楚起见,你可以重构方法。我假设异常是检查异常。
private void doSomethingHelper() throws ExceptionA, ExceptionB {
try {
// do something
} catch( ExceptionA e) {
// actions for ExceptionA
throw e;
} catch( ExceptionB e) {
// actions for ExceptionB
throw e;
}
}
public void doSomething() {
try {
doSomethingHelper();
} catch( ExceptionA | ExceptionB e ) {
// Actions for exceptions A or B
}
}