捕获多个异常时的特定和相同的操作

2022-09-04 20:21:22

我想以不同的方式处理两种不同类型的异常,然后对这两种异常类型进行一些相同的操作。如何在Java中做到这一点?

下面的代码显示了我想要执行的操作,但它不正确,因为一个异常不能捕获两次。

正确的语法是什么?

try {
    // do something...
} 
catch (ExceptionA e) {
    // actions for ExceptionA
}
catch (ExceptionB e) {
    // actions for ExceptionB
}
catch (ExceptionA | ExceptionB e) {
    // actions for ExceptionA & ExceptionB
}

答案 1

使用构造。在块中,首先分别检查和处理异常类型。在此之后,对两种类型进行通用处理。通过这种方式,您可以在一个块中完成所有操作:catch (ExceptionA | ExceptionB e)catchinstanceofecatch

try {
    // do something...
} catch (ExceptionA | ExceptionB e) {
    if (e instanceof ExceptionA) {
        // handling for ExceptionA
    } else {
        // handling for ExceptionB
    }
    // common handling for both exception types
}

答案 2

对公共代码使用方法。

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
}

这将适用于大多数事情。
虽然有一些例外,如.为此,您可以返回,无论调用方是否必须返回,并将其用作:returndoCommon

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 而突然完成 try 块的执行,则有一个选择:

如果 V 的运行时类型赋值与 try 语句的任何 catch 子句的可捕获异常类 (§5.2) 兼容,则选择第一个(最左侧)此类 catch 子句。值 V 被分配给所选 catch 子句的参数,并执行该 catch 子句的 Block,然后有一个选择:

如果该块正常完成,则 try 语句正常完成。

如果该块由于任何原因突然完成,则 try 语句会出于同样的原因突然完成。

如果运行时类型 V 的赋值与 try 语句的任何 catch 子句的可捕获异常类不兼容,则 try 语句会由于值 V 的抛出而突然完成。

因此,只执行应用的第一个 catch 块。无法为同一 try 语句执行两个 catch 块。


推荐