为什么在Java中捕获异常,何时可以捕获Throwables?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (42)

我们最近遇到了一个Java服务器应用程序的问题,其中应用程序抛出的错误没有被捕获,因为Error是Throwable的一个单独的子类,我们只捕获异常。

我们通过捕获Throwables而不是Exception来解决眼前的问题,但是这让我想到了为什么你会想要捕获Exceptions而不是Throwables,因为你会错过错误。

那么,为什么你要捕获异常,当你可以捕获Throwables

提问于
用户回答回答于

这一切都取决于您在发现错误后要做什么。一般来说,捕捉错误可能不应被视为您的“正常”异常流程的一部分。如果你确实抓住了一个,那么你不应该考虑“继续进行,因为JVM(和各种库)将使用错误作为表示”发生了真正严重的事情并且我们需要尽快关闭“。一般来说,最好在他们告诉你最后的结果时倾听他们。

另一个问题是,错误的可恢复性或不可能取决于特定的虚拟机,这是您可能无法控制的。

也就是说,有一些角落案例可以安全和/或需要捕获错误或至少某些子类:

  • 有些情况下你确实想要停止正常的流程:例如,如果你在一个Servlet中,你可能不希望Servlet运行器的默认异常处理程序向世界宣布你有一个OutOfMemoryError,无论是不是你可以从中恢复过来。
  • 偶尔,JVM可以从错误原因中彻底恢复的情况下会抛出一个错误。例如,如果尝试分配数组时发生OutOfMemoryError,至少在Hotspot中,似乎可以安全地从此恢复。(当然还有其他一些情况,如果尝试和犁地不安全,可能会抛出OutOfMemoryError。)

所以底线是:如果你确实捕获了Throwable / Error而不是Exception,那么它应该是一个明确定义的情况,即你知道你在做“特别的事情”

编辑:可能这是显而易见的,但我忘了说在实践中,JVM可能实际上不会在错误上调用catch子句。我已经明确地看到热点试图捕捉某些OutOfMemoryErrors和NoClassDefFoundError。

用户回答回答于

从Java API文档:

该类Exception及其子类是一种Throwable表示合理应用程序可能想要捕获的条件的形式。 An Error是其中的一个子类Throwable,表示合理应用程序不应试图捕捉的严重问题。

错误通常是低级的(例如,由虚拟机引发),并且不应该被应用程序捕获,因为可能无法实现合理的连续性。

扫码关注云+社区