java - 为什么以相反的执行顺序处理 try-with-resource 的抑制异常?

标签 java exception try-with-resources

在正常的 try-catch-finally 中,像这样,

try {
    throw new ExceptionA();
} finally {
    throw new ExceptionB();
}

ExceptionA 在 Exception B 之前抛出。ExceptionA 将被抑制。

但是在 try-with-resource 中,像这样,

try ( // declare resource that throw ExceptionA in close method ) {
    throw new ExceptionB();
}

ExceptionA 在ExceptionB 之后抛出。 ExceptionA 将被抑制。

为什么它们抑制异常的顺序不同?

最佳答案

当你使用 try 和 finally 而没有使用 try-with-resources 时,当 try block 中出现问题时,你会抛出异常,然后执行 finally,如果在 finally block 期间抛出异常,则异常finally 抛出的异常屏蔽 try block 抛出的异常。 “异常屏蔽”是 JVM 选择从 try-finally 中抛出的异常是来自 finally block 的异常,而不是原始异常。这可能非常糟糕,因为 try block 抛出的异常是包含错误信息的异常,而 finally block 抛出的异常通常只是噪音。所以在你上面的例子中有异常(exception) A,从实现者的角度来看,发生的事情是直观的,但它对应用程序开发人员没有用;有关实际出错的有值(value)的信息在 A 中,您丢失了它,而抛出的是 B,而 B 的堆栈跟踪是您在阅读日志文件时看到的。

例如:我的代码进行了一个 JDBC 调用,该调用抛出一个异常,行号告诉我错误发生的位置,我可以映射回供应商代码的 SQLState 告诉我出了什么问题,但是当关闭语句时或者连接出现网络故障,因为 JDBC 对象告诉服务器服务器应该清理什么,我得到一个破损的管道异常。除非您对异常处理非常彻底,否则很容易用损坏的管道掩盖有用的异常,即您无能为力且不关心的异常。

try-with-resources 特性试图确保提供信息的异常不会被关闭时抛出的偶然异常所掩盖,try block 中抛出的异常就是被抛出的异常,以及由 close 方法抛出的异常出路被抑制,这意味着它被添加到 try block 的异常中(除非 try block 中没有抛出任何东西,在这种情况下,关闭时抛出的异常就是抛出的异常)。

所以这是一个变化,但它在减少有值(value)的异常被无意中掩盖的可能性方面是一个很大的改进。

关于java - 为什么以相反的执行顺序处理 try-with-resource 的抑制异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31482114/

相关文章:

c# - 无法将 COM 对象转换为类类型

java-7 - try-with-resources:Java 是否对 .close() 的调用顺序做出任何保证?

java.nio.file.FileSystemException :/proc: Too many open files

java - Spark Streaming reduceByKeyAndWindow 示例

java - 如果我在另一个静态方法中调用静态方法,Java程序如何加载

java - 整洁的代码: Using prefix get for java function name

尽管代码正确,但 JavaFX 程序无法运行?

java - 在系统检查异常之前,如何允许输入三个整数,后跟一个空格和一个单词?

java - 扩展的 try-with-resources 语句到底捕获了什么?

java - 在类中存储 byte[]