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

时间:2015-08-07 13:18:35

标签: java exception-handling try-catch java-7

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

以下代码显示了我想要做的事情,但它不正确,因为一个例外无法捕获两次。

这个的正确语法是什么?

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

5 个答案:

答案 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;
    }
}

如果您希望将contentDeterminationFailedsizeDeterminationFailed作为单个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
    }
}