4

我不明白什么时候使用multi catch。我看到一些帖子,编译时多捕获异常类型是多异常类型中最接近的超类型。

假设有异常类型 A、B 和它们最接近的超类型 C。

选项1

try{//whatever}
catch(A|B ex){//whatever}

选项 2

try{//whatever}
catch(C ex){//whatever}

选项 3

try{//whatever}
catch(A ex){//whatever}
catch(B ex){//whatever}

当抛出多个异常时,我们应该在哪些理想情况下使用上述选项?

4

4 回答 4

7

根据Oracle 文档,新的 multi-catch 块的值得注意的点是:

catch (IOException|SQLException ex) {
   logger.log(ex);
   throw ex;
} 

如果一个 catch 块处理多个异常类型,则 catch 参数是隐式 final。在此示例中,catch 参数 ex 是最终参数,因此您不能在 catch 块中为其分配任何值。通过编译处理多种异常类型的 catch 块生成的字节码将比编译许多只处理一种异常类型的 catch 块更小(因此更优越)。处理多种异常类型的 catch 块不会在编译器生成的字节码中产生重复;字节码没有异常处理程序的复制。

如果可以以不同方式处理异常,那么我相信您应该分别捕获它们。如果多个异常的异常处理相同,则可以使用 multi-catch 块。

try{//whatever}
catch(A ex){//do something specific for A}
catch(B ex){//do something specific for B}

try{//whatever}
catch(C ex){
 //C is superclass of A and B and you are not concerned about the specific type 
 // will catch even other exceptions which are instanceof C
}

try{//whatever}
catch(A|B ex){//do the same thing for both A and B}
于 2013-06-27T05:57:28.737 回答
3

选项 1:避免重复代码,如果AB将被以相同的方式处理。

} catch (SSLException | UnknownHostException e) {
   showErrorPopupAndReturn();
}

选项 2:与选项 1 几乎相同,但它还将处理C您可能不想要的任何其他子类型。

} catch (IOException e) {
   // Almost as Option 1, but will also handle any other subclass of
   // IOException, e.g. ObjectStreamException
   doStuff();
}

选项 3:A当或B发生时,您必须做其他事情。

} catch (UnknownHostException e) {
    tryAnotherIPaddress();
} catch (SSLException e) {
    reloadCertificate();
}
于 2013-06-27T06:03:05.647 回答
0

这取决于您如何处理异常。

情况 1 两种类型的异常都被捕获并处理

在情况 2 中,它仅被捕获类型 C 并且它的子类型异常和句柄

情况 3 A 和 B 类型分别处理。

案例1和3的最终结果是相同的。但在案例 3 中,代码的可理解性或可读性会增加

于 2013-06-27T06:10:25.750 回答
0

何时使用每个选项:

选项 1:A 或 B 没有共同的超类,但处理它们的代码将相同

选项 2:A 和 B 将 C 作为共同的超类,您只是不介意并将它们视为相同

选项 3:A 必须与 B 区别对待

于 2013-06-27T05:59:06.883 回答