问题
这个问题在这里已有答案:
- 我可以在同一个catch子句中捕获多个Java异常吗? 9个答案
我需要捕获两个异常,因为它们需要相同的处理逻辑。我想做的事情如下:
catch (Exception e, ExtendsRuntimeException re) {
// common logic to handle both exceptions
}
是否可以避免在每个catch块中复制处理程序代码?
#1 热门回答(178 赞)
Java 7及更高版本
支持Multiple-exception catches,从Java 7开始。
语法是:
try {
// stuff
} catch (Exception1 | Exception2 ex) {
// Handle both exceptions
}
静态类型ex
是列出的异常中最专业的常见超类型。有一个很好的功能,如果你在catch中重新编程ex
,编译器知道只能抛出一个列出的异常。
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
}
如果异常处理程序需要访问在try
之前声明的局部变量,这会变得混乱。如果处理程序方法需要重新抛出异常(并且已经检查),那么你将遇到签名的严重问题。具体来说,handleException
必须声明为throwSuperException
...这可能意味着你必须更改封闭方法的签名,依此类推。
##方法#2
try {
// stuff
} catch (SuperException ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
// handle exception
} else {
throw ex;
}
}
再次,我们有签名的潜在问题。
##方法#3
try {
// stuff
} catch (SuperException ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
// handle exception
}
}
如果你遗漏了else
part(例如因为目前没有其他的SuperException
子类型),代码就会变得更加脆弱。如果重组了异常层次结构,那么没有aelse
的这个处理程序最终可能会默默地吃异常!
#2 热门回答(33 赞)
Java <= 6.x只允许你为每个catch块捕获一个异常:
try {
} catch (ExceptionType name) {
} catch (ExceptionType name) {
}
Documentation:>每个catch块都是一个异常处理程序,它处理由其参数指示的异常类型。参数类型ExceptionType声明了处理程序可以处理的异常类型,并且必须是从Throwable类继承的类的名称。
对于Java 7,你可以在一个catch块上捕获多个Exception:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
Documentation:>在Java SE 7及更高版本中,单个catch块可以处理多种类型的异常。此功能可以减少代码重复并减少捕获过于宽泛的异常的诱惑。
参考:http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
#3 热门回答(12 赞)
如果你不在Java 7上,则可以将异常处理提取到方法 - 这样你至少可以最小化重复
try {
// try something
}
catch(ExtendsRuntimeException e) { handleError(e); }
catch(Exception e) { handleError(e); }