如何解决为什么 Java 公开 Error 和 Java SE API 回调方法接受 Throwable 而不是 Exception?
事实
- Java SE API 说明了它 "indicates serious problems that a reasonable application should not try to catch" 的
Error
类型;还有"errors are abnormal conditions that should never occur"。 - 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
引起,如果原始 Error
是 OutOfMemoryError
,这一点尤其明显)。
问题
- 鉴于
Error
表示不应该发生的异常情况并且应用程序不应尝试捕获它,那么在 Java SE API 中完全公开Error
类型的充分理由是什么?总是通过终止虚拟机而不将它们暴露给应用程序来处理错误? - 为什么(几乎?)Java SE API 中的所有回调方法,例如
java.nio.channels.CompletionHandler.failed
、CompletionStage.exceptionally
、Flow.Subscriber.onError
,都接受Throwable
,其中包括{{1 }},而不是接受Error
?实际上,接受Exception
的回调并不比捕获Throwable
的代码更好(完成此类回调的代码必须捕获Error
才能传递它,从而违反了Error
类的推荐)。这样的回调迫使用户要么
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。