我知道引入了try-with-resources语句来治愈(或防止异常屏蔽)。
考虑以下代码:
class TestExceptionSuppressing {
public static void main(String[] args) {
try {
testMethod();
} catch (Exception e) {
System.out.println(e.getMessage());
for (Throwable t : e.getSuppressed()) {
System.err.println("Suppressed Exceptions List: " + t);
}
}
}
static void testMethod() {
try (InnerClass inner = new InnerClass()) {
throw new IOException("Exception thrown within try block");
} catch (Exception e) {
throw new RuntimeException(
"Exception thrown within catch block.Hence exception thrown within try block will be lost (or) masked");
}
}
static class InnerClass implements AutoCloseable {
@Override
public void close() throws Exception {
throw new Exception("Exception thrown in close method will be tacked on to existing exceptions");
}
}
}
输出:在catch块中引发的异常。因此在try块中引发的异常将丢失(或)被屏蔽
显然,在testMethod()的catch块中引发的异常掩盖了在try块中引发的io异常,也屏蔽了被抑制并添加到此io异常(在close方法中抛出的异常)
此代码示例可能证明try-with-resources可能无法完全防止异常屏蔽。
我知道这里的情况很复杂,可能会感到困惑,但可能会发生。 我的问题是,是否有一种方法可以防止这种情况发生,即即使使用try-with-resources语句,异常屏蔽仍然会发生?
答案 0 :(得分:4)
如果使用RuntimeException(String, Throwable)
,则可以保留原始异常使用指定的详细消息和原因构造一个新的运行时异常。
throw new RuntimeException(
"Exception thrown within catch block won't be lost (or) masked", e);
如果要添加抑制的try and resources异常,则需要使用addSuppressed(Throwable)方法,具体情况如下:
RuntimeException runtimeException = new RuntimeException(
"Exception thrown within try block won't be lost (or) masked", e);
runtimeException.addSuppressed(e.getSuppressed()[0]);
Suppressed Exceptions and Try With Resources中的更多信息
但是,仅因为在这种情况下CloseException被抑制,并不意味着该被抑制的异常已被忽略。为了解决这种抑制异常的概念,在Java 7中向java.lang.Throwable类添加了两个新方法和一个构造函数。
public final void addSuppressed(Throwable exception)