微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 Java 公开 Error 和 Java SE API 回调方法接受 Throwable 而不是 Exception?

如何解决为什么 Java 公开 Error 和 Java SE API 回调方法接受 Throwable 而不是 Exception?

事实

  1. Java SE API 说明了它 "indicates serious problems that a reasonable application should not try to catch"Error 类型;还有"errors are abnormal conditions that should never occur"
  2. JLS 11.1.3“异步异常”说明 VirtualMachineError一个 "internal error or resource limitation in the Java Virtual Machine that prevents it from implementing the semantics of the Java programming language"

解释

规范不仅明确建议不要捕获 Error,而且还说如果 VirtualMachineError 发生,则无法保证语言语义成立。看来,arguments against Thread.stop/ThreadDeath 至少也可以应用于任何 VirtualMachineError。由于 lazy resolution 被允许,LinkageError 也是如此:没有代码期望它或防范它,因此当它发生时,它可能会导致破坏对象的状态,就像 {{1} }} 或 ThreadDeath

以上似乎(对我而言)足以决定没有可靠的方法来处理 VirtualMachineError。我看到的唯一出路是有一个 Error 调用 Thread.UncaughtExceptionHandler/System.exit 并且可能尝试在终止 VM 之前记录 Runtime.halt(记录尝试可能只是失败另一个 Error 由原始 Error 引起,如果原始 ErrorOutOfMemoryError,这一点尤其明显)。

问题

  1. 鉴于 Error 表示不应该发生的异常情况并且应用程序不应尝试捕获它,那么在 Java SE API 中完全公开 Error 类型的充分理由是什么?总是通过终止虚拟机而不将它们暴露给应用程序来处理错误
  2. 为什么(几乎?)Java SE API 中的所有回调方法,例如java.nio.channels.CompletionHandler.failedCompletionStage.exceptionallyFlow.Subscriber.onError,都接受Throwable,其中包括{{1 }},而不是接受Error?实际上,接受 Exception 的回调并不比捕获 Throwable代码更好(完成此类回调的代码必须捕获 Error 才能传递它,从而违反了Error 类的推荐)。这样的回调迫使用户要么
    • ? 还传播 Error,它只是将处理 Throwable 延迟到以后,并导致更多代码在处理之前运行,从而增加抛出另一个 Error 的机会(再次,对于 Error 很明显)。
    • ? 将 OutOfMemoryError 包裹在 Error 中,这只是有害的,因为它有效地隐藏了 Exception 发生的事实,使其无法以任何直接的方式检测。立>
    • ? 处理 Error,这似乎除了终止 VM 之外是不可能的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。