在Java中是否可以在同一个catch块中捕获两个异常?

use*_*818 108 java exception-handling try-catch

我需要捕获两个异常,因为它们需要相同的处理逻辑.我想做的事情如下:

catch (Exception e, ExtendsRuntimeException re) {
    // common logic to handle both exceptions
}
Run Code Online (Sandbox Code Playgroud)

是否可以避免重复每个catch块中的处理程序代码?

Ste*_*n C 196

Java 7及更高版本

从Java 7开始支持多异常捕获.

语法是:

try {
     // stuff
} catch (Exception1 | Exception2 ex) {
     // Handle both exceptions
}
Run Code Online (Sandbox Code Playgroud)

静态类型ex是列出的例外中最专业的常见超类型.有一个很好的功能,如果你重新抛出excatch,编译器知道只能抛出一个列出的异常.


Java 6及更早版本

在Java 7之前,有一些方法可以解决这个问题,但它们往往不够优雅,而且有局限性.

方法#1

try {
     // stuff
} catch (Exception1 ex) {
     handleException(ex);
} catch (Exception2 ex) {
     handleException(ex);
}

public void handleException(SuperException ex) {
     // handle exception here
}
Run Code Online (Sandbox Code Playgroud)

如果异常处理程序需要访问在之前声明的局部变量,这会变得混乱try.如果处理程序方法需要重新抛出异常(并且已经检查),那么您将遇到签名的严重问题.具体来说,handleException必须声明为throw SuperException...这可能意味着您必须更改封闭方法的签名,依此类推.

方法#2

try {
     // stuff
} catch (SuperException ex) {
     if (ex instanceof Exception1 || ex instanceof Exception2) {
         // handle exception
     } else {
         throw ex;
     }
}
Run Code Online (Sandbox Code Playgroud)

再次,我们有签名的潜在问题.

方法#3

try {
     // stuff
} catch (SuperException ex) {
     if (ex instanceof Exception1 || ex instanceof Exception2) {
         // handle exception
     }
}
Run Code Online (Sandbox Code Playgroud)

如果你遗漏了else部分(例如因为目前没有其他的子类型SuperException),代码就会变得更加脆弱.如果重新组织了异常层次结构,那么没有a的这个处理程序else最终可能会默默地吃异常!

  • @emory我可能错了,但例外是对象.那么你不能使用`instanceof`函数来查看你的异常对象在catch语句中是一种类型还是另一种类型?所以你可以捕获,执行常用代码,然后使用`instanceof`的块来执行不同的代码. (2认同)

Fra*_*eth 33

Java <= 6.x只允许您为每个catch块捕获一个异常:

try {

} catch (ExceptionType name) {

} catch (ExceptionType name) {

}
Run Code Online (Sandbox Code Playgroud)

文档:

每个catch块都是一个异常处理程序,它处理由其参数指示的异常类型.参数类型ExceptionType声明了处理程序可以处理的异常类型,并且必须是从Throwable类继承的类的名称.

对于Java 7,您可以在一个catch块上捕获多个Exception:

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}
Run Code Online (Sandbox Code Playgroud)

文档:

在Java SE 7及更高版本中,单个catch块可以处理多种类型的异常.此功能可以减少代码重复并减少捕获过于宽泛的异常的诱惑.

参考: http : //docs.oracle.com/javase/tutorial/essential/exceptions/catch.html


jef*_*eff 12

如果您不在Java 7上,则可以将异常处理提取到方法中 - 这样您至少可以最小化重复

try {
   // try something
}
catch(ExtendsRuntimeException e) { handleError(e); }
catch(Exception e) { handleError(e); }
Run Code Online (Sandbox Code Playgroud)