Throwable 类有一个名为 addSuppressed() 的方法,该方法将 Throwable 对象作为参数。使用 addSuppressed() 方法可以将被抑制的异常添加到另一个异常中,以备不时之需。下面的示例展示了如何手动将抑制异常添加到 Java 异常中:
package com.hxstrive.jdk7.try_with_resources; /** * JDK7 新特性 try-with-resources * @author hxstrive.com */ public class TryWithResourcesDemo12 { static class MyResource implements AutoCloseable { @Override public void close() throws Exception { throw new Exception("MyResource.close error"); } public void doSomething(String message) { System.out.println("doSomething() message=" + message.toUpperCase()); } } public static void main(String[] args) throws Exception { // 定义一个异常,用于捕获try-with-resources中的异常 Exception finalException = null; try (MyResource resource = new MyResource()) { resource.doSomething("hello"); resource.doSomething(null); // NullPointerException } catch (Exception e) { finalException = new Exception("finally", e); // 将异常 e 添加到 finalException 异常链中 finalException.addSuppressed(e); for(Throwable item : e.getSuppressed()) { finalException.addSuppressed(item); } } finally { if(null != finalException) { throw finalException; } } //结果: //doSomething() message=HELLO //Exception in thread "main" java.lang.Exception: finally // at com.hxstrive.jdk7.try_with_resources.TryWithResourcesDemo12.main(TryWithResourcesDemo12.java:27) // Suppressed: java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because "message" is null // at com.hxstrive.jdk7.try_with_resources.TryWithResourcesDemo12$MyResource.doSomething(TryWithResourcesDemo12.java:17) // at com.hxstrive.jdk7.try_with_resources.TryWithResourcesDemo12.main(TryWithResourcesDemo12.java:25) // Suppressed: java.lang.Exception: MyResource.close error // at com.hxstrive.jdk7.try_with_resources.TryWithResourcesDemo12$MyResource.close(TryWithResourcesDemo12.java:13) // at com.hxstrive.jdk7.try_with_resources.TryWithResourcesDemo12.main(TryWithResourcesDemo12.java:23) // Suppressed: [CIRCULAR REFERENCE: java.lang.Exception: MyResource.close error] //Caused by: [CIRCULAR REFERENCE: java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because "message" is null] } }
注意 Throwable 引用必须在 try-with-resources 结构之外声明。否则,catch 和 finally 块就无法访问它。
在大多数情况下,您不需要手动将抑制异常添加到异常中,但现在您至少看到了如何做到这一点,以备不时之需。