可以使用try-with-resources语句完全防止异常屏蔽

时间:2018-11-05 05:56:17

标签: java exception try-with-resources

我知道引入了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语句,异常屏蔽仍然会发生?

1 个答案:

答案 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)