java - 为什么 Java 公开 Error 和 Java SE API 回调方法接受 Throwable 而不是 Exception?
问题描述
事实
- Java SE API 说它“表示一个合理的应用程序不应该试图捕捉的严重问题”
Error
的类型;还有“错误是不应该发生的异常情况”。 - JLS 11.1.3“异步异常”说
VirtualMachineError
这是“Java 虚拟机中的内部错误或资源限制,阻止它实现 Java 编程语言的语义”。
解释
不仅规范明确建议不要捕获Error
s,而且还说如果VirtualMachineError
发生,则不能保证语言语义不变。看来反对Thread.stop
/的论点ThreadDeath
至少也可以应用于任何VirtualMachineError
。由于允许延迟解析,对于 : 也是如此LinkageError
:没有代码期望它或防范它,所以当它发生时,它可能会导致像ThreadDeath
or一样破坏对象的状态VirtualMachineError
。
以上似乎(对我而言)足以决定没有可靠的方法来处理Error
s。我看到的唯一方法是Thread.UncaughtExceptionHandler
调用System.exit
/Runtime.halt
并且可能会Error
在终止 VM 之前尝试记录 (记录尝试可能会简单地失败,而另一个记录尝试可能会Error
因原始记录尝试而失败,如果原始记录尝试是 则尤其明显Error
)OutOfMemoryError
。
问题
- 鉴于 an
Error
表示不应该发生的异常情况并且应用程序不应该尝试捕获它,那么Error
在 Java SE API 中完全公开类型而不是总是通过终止 VM 而不将它们暴露给应用程序来处理错误的充分理由是什么? - 为什么(几乎?)Java SE API 中的所有回调方法,例如,、、、accept ,
java.nio.channels.CompletionHandler.failed
其中包括,而不是accept ?实际上,接受的回调并不比捕获 an的代码好(并且完成此类回调的代码必须捕获 an才能传递它,从而违反了类的建议)。这样的回调迫使用户要么CompletionStage.exceptionally
Flow.Subscriber.onError
Throwable
Error
Exception
Throwable
Error
Error
Error
- 还传播
Throwable
它只是将处理Error
a 延迟到以后的时间,并导致更多代码在处理之前运行,从而增加了抛出另一个的机会Error
(同样,对于 a 来说很明显OutOfMemoryError
)。 - 将 s包裹
Error
在Exception
s 中,这只是有害的,因为它Error
通过使其无法以任何直接的方式检测到,从而有效地隐藏了发生的事实。 - 处理
Error
s,除了终止 VM 之外,这似乎是不可能的。
- 还传播
解决方案
推荐阅读
- css - 无法将 ul.width 移动到 width:0px
- java - 二进制搜索程序未打印正确的索引
- r - 使用 selectInput 选择输入时提取相应的数值
- amazon-web-services - lambda aws 连接失败 - 将 ETIMEDOUT 错误连接到 2 个外部 ip
- c - 在 C 中接受多个用户输入
- selenium - Selenium - webdriver 实例何时更新?
- airflow - 在另一个任务中访问来自 SimpleHTTPOperator 的响应
- firebase-realtime-database - 如何使我的实时数据库只能由我的用户读取?
- html - AngularJS ng-repeat-start ng-repeat-end 带有表格和两行的动态行跨度
- python - 如何列出numpy数组中的最小值