关于Java.lang.Error的问题

时间:2010-08-30 12:15:16

标签: java exception throwable

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

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

3 个答案:

答案 0 :(得分:1)

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

JVM中非VirtualMachineErrors的大多数错误都是本机库可能已损坏其静态状态的情况 - 例如AWTError,ZipError。

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

答案 1 :(得分:1)

所有规则都有例外(除此之外)。

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

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

  1. 修复编程错误 (AssertionError,StackOverflowError)
  2. 修复配置错误 (UnsatisfiedLinkError)
  3. 更正JVM大小调整参数(OutOfMemoryError)
  4. 这种处理应该在调用堆栈中(即在main()附近)非常“高”地完成,其中执行主循环(或等效)。我认为在深层代码中捕获Error并不是一个好习惯,在这些情况下至少应该重新抛出错误。

答案 2 :(得分:0)

此处已回答类似问题 - When to catch java.lang.Error?

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