3

有很多帖子java.lang.Error说它不应该被抓住。我的问题是它是否不应该被关注它的用途是什么。因为它是 Throwable 所以我们可以在 try catch 中捕获它。我读了一些帖子,比如只有在某些情况下才应该被抓住,如何知道这些情况。

简而言之,我想知道当我捕获错误时会出现什么问题。它背后的过程是什么。为什么他们制作了 Error 及其子类?如果我的应用程序不应该捕获它们,那么什么会捕获它们?为什么我的代码无法处理这个捕获的错误?如果我只是捕获一个错误并在 Catch 块中编写一些处理代码,那么该代码不会运行吗?

4

3 回答 3

1

所有规则都有例外(除了这个)。

即使每个人都说不应该,但在很多情况下捕获这些 java.lang.Error 是完全合适的。该规则背后的逻辑是:“在检测到致命情况后不要尝试继续运行您的应用程序”。因此,在抛出此类错误后,您必须小心在做某事之前。之后系统可能无法继续其任务。

servlet 捕获 OutOfMemoryError、记录错误并销毁会话可能是可以的。也许问题出在那个精确的会话上。销毁它会恢复内存并允许其他用户继续使用系统。但是,您应该有一种机制来实时跟踪这些错误,以便:

  1. 修复编程错误(AssertionError、StackOverflowError)
  2. 修复配置错误 (UnsatisfiedLinkError)
  3. 更正 JVM 大小调整参数 (OutOfMemoryError)

这种处理应该在调用堆栈中非常“高”地完成(即在 main() 附近),主循环(或等效循环)在此执行。我认为在深度代码中捕获错误不是一个好习惯,您至少应该在这些情况下重新抛出错误。

于 2010-08-30T13:52:07.880 回答
1

错误(尤其是 VirtualMachineError 的子类)表明 JVM 遇到了内部问题——这意味着它的内部状态可能不再一致。如果您捕获错误并尝试恢复,则未来的行为是不确定的。错误是 Throwable 的原因是它们可以被抛出 - 例如,您可以自己处理无法恢复的本机库中的错误(例如,库可能已写入 JVM 内存,或损坏其内部静态状态)。在所有 Throwables 的情况下都使用相同的堆栈遍历和堆栈跟踪生成机制——如果有另一种机制来做同样的事情,那将是愚蠢的。

JVM 中大多数不是 VirtualMachineErrors 的错误都是本地库可能破坏其静态状态的情况 - 例如 AWTError、ZipError。

然而,在极少数情况下捕获错误是正常的:测试框架中的 AssertionError 和 LinkageError ,您必须在运行时处理不同版本库的缺失/存在。这是一个非常罕见的要求,可以通过反射更好地处理。

于 2010-08-30T12:32:33.960 回答
0

此处已经回答了类似的问题 -何时捕获 java.lang.Error?

基本上,你永远不应该试图抓住它,因为它抛出了相当严重的问题,比如你的线程由于某种原因死了,并且无法恢复。但是,有时需要在处理上述 URL 中所述的框架本身时捕获错误。

于 2010-08-30T12:19:53.990 回答