Java捕获多个异常,重新抛出异常

在Java 7中,捕获块已经改进,可以在单个捕获块中处理多个异常。如果你正在捕获多个相似的异常并且它们有相似的代码,那么使用这个功能将减少代码重复。让我们通过一个例子来了解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(IOException | SQLException ex){
     logger.error(ex);
     throw new MyException(ex.getMessage());
}

如果一个捕获块处理多个异常,你可以使用竖线(|)将它们分开,在这种情况下,异常参数(ex)是final的,所以你不能改变它。这个特性生成的字节码更小,减少了代码冗余。

Java重新抛出异常

另一个改进是在重新抛出异常的编译器分析方面。Java重新抛出异常允许你在方法声明的throws子句中指定更具体的异常类型。让我们通过一个小例子来看看这个特性:

package com.journaldev.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中的异常处理

Source:
https://www.digitalocean.com/community/tutorials/java-catch-multiple-exceptions-rethrow-exception