Java异常处理详解:多重异常捕获与重新抛出最佳实践
在Java 7中,catch块已经得到改进,可以在一个catch块中处理多个异常。如果你正在捕获多个异常且它们具有相似的代码,那么使用这个特性将减少代码重复。让我们通过一个例子来了解Java捕获多个异常的特性。
在Java中捕获多个异常
在Java 7之前,我们习惯按照下面的方式逐个捕获多个异常。
catch (IOException ex) {
logger.error(ex);
throw new MyException(ex.getMessage());
}
catch (SQLException ex) {
logger.error(ex);
throw new MyException(ex.getMessage());
}
在Java 7中,我们可以将这两个异常都在一个catch块中捕获,如下所示:
catch(IOException | SQLException ex){
logger.error(ex);
throw new MyException(ex.getMessage());
}
如果一个catch块处理多个异常,你可以使用一个竖线(|)来分隔它们,在这种情况下,异常参数(ex)是final的,所以你不能改变它。这个特性生成的字节码更小,并减少代码冗余。
Java重新抛出异常
在编译器分析重新抛出异常方面进行了另一项改进。Java重新抛出异常允许您在方法声明的throws子句中指定更具体的异常类型。让我们通过一个小例子来看看这个改进。
package com.Olivia.util;
public class Java7MultipleExceptions {
public static void main(String[] args) {
try{
rethrow("abc");
}catch(FirstException | SecondException | ThirdException e){
//由于e是final的,下面的赋值将抛出编译时异常
//e = new Exception();
System.out.println(e.getMessage());
}
}
static void rethrow(String s) throws FirstException, SecondException,
ThirdException {
try {
if (s.equals("First"))
throw new FirstException("First");
else if (s.equals("Second"))
throw new SecondException("Second");
else
throw new ThirdException("Third");
} catch (Exception e) {
//下面的赋值会禁用Java 7改进的重新抛出异常类型检查功能
// e=new ThirdException();
throw e;
}
}
static class FirstException extends Exception {
public FirstException(String msg) {
super(msg);
}
}
static class SecondException extends Exception {
public SecondException(String msg) {
super(msg);
}
}
static class ThirdException extends Exception {
public ThirdException(String msg) {
super(msg);
}
}
}
你可以看到,在rethrow方法中,catch块捕获了Exception,但它并不是throws子句的一部分。Java 7编译器分析完整的try块,检查抛出的异常类型,然后从catch块重新抛出异常。请注意,如果你改变catch块的参数,这个分析将被禁用。更多阅读:Java中的异常处理。