问题描述
事实
- 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 (将#修改为@)