我们最近遇到了一个Java服务器应用程序的问题,该应用程序抛出的错误没有被捕获,因为Error是Throwable的一个单独的子类,而我们只捕获异常。
我们通过捕获Throwables而不是异常解决了直接的问题,但这让我思考为什么你会想要捕获异常,而不是Throwables,因为那样你就会错过错误。
那么,既然可以捕获Throwables,为什么还要捕获异常呢?
发布于 2009-02-24 14:29:27
这在一定程度上取决于您在捕获错误后如何处理它。一般来说,捕获错误可能不应该被视为“正常”异常流的一部分。如果你真的捕获了一个错误,你不应该想着“像什么都没有发生一样继续下去”,因为JVM (和各种库)会使用错误作为一种信号,表示“发生了真正严重的事情,我们需要尽快关闭”。一般来说,当他们告诉你世界末日即将来临时,最好还是听从他们的话。
另一个问题是,错误的可恢复性或不可恢复性可能取决于特定的虚拟机,这是您可能控制或无法控制的东西。
也就是说,在少数情况下,捕获错误或至少某些子类是安全和/或可取的:
在某些情况下,你确实想要停止正常的流程:例如,如果你在一个Servlet中,你可能不希望Servlet运行器的默认异常处理程序向全世界宣布你已经有了一个it.
所以底线是:如果你确实捕获了Throwable/Error而不是Exception,那么它应该是一个你知道你正在“做一些特殊的”的定义良好的情况。
编辑:这可能是显而易见的,但我忘了说,在实践中,捕获JVM可能不会在错误时实际调用子句。我肯定看到过Hotspot巧妙地掩盖了捕获某些OutOfMemoryErrors和NoClassDefFoundError的尝试。
发布于 2009-02-24 14:14:59
在Java API文档中:
类
Exception
及其子类是Throwable
的一种形式,表示合理的应用程序可能希望捕获的条件。
Error
是Throwable
的子类,用于指示合理的应用程序不应尝试捕获的严重问题。
错误通常是低级别的(例如,由虚拟机引发),并且不应该被应用程序捕获,因为合理的继续可能是不可能的。
发布于 2009-02-24 20:00:22
许多其他的答案都过于狭隘地看待事物。
正如他们所说,如果您正在编写应用程序代码,则不应捕获Throwable。您对此无能为力,所以最好让周围的系统(JVM或框架)来处理这些问题。
但是,如果您正在编写“系统代码”,比如框架或其他低级代码,那么您可能非常希望捕获Throwable。原因是尝试报告异常,可能是在日志文件中。在某些情况下,您的日志记录将失败,但在大多数情况下,它将成功,并且您将获得解决问题所需的信息。一旦您进行了日志记录尝试,您就应该重新抛出、终止当前线程或退出整个JVM。
https://stackoverflow.com/questions/581878
复制相似问题