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 块就无法访问它。
在大多数情况下,您不需要手动将抑制异常添加到异常中,但现在您至少看到了如何做到这一点,以备不时之需。