当前位置:  开发笔记 > 编程语言 > 正文

为什么捕获Throwables时会捕获Java中的异常?

如何解决《为什么捕获Throwables时会捕获Java中的异常?》经验,为你挑选了5个好方法。

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

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

所以,当你能捕获Throwables时,你为什么要捕捉异常呢?



1> Ferdinand Be..:

从Java API文档:

该类Exception及其子类是一种Throwable表示合理的应用程序可能想要捕获的条件的形式.

An Error是一个子类Throwable,表示合理的应用程序不应该试图捕获的严重问题.

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


您可以记录消息以显示应用程序已死亡的原因.
捕获Throwable时要做的一件合理的事情就是记录"它为什么会发生".但问题是记录器实际上是否可用,让我们说VirtualMachineError?是否有一个明确声明安全列表的javadoc - 100%不可恢复错误,100%可恢复错误和模糊状态错误?

2> Neil Coffey..:

这一切都取决于你在捕获它后会对错误做些什么.通常,捕获错误可能不应被视为"正常"异常流程的一部分.如果你确实抓到一个,你不应该考虑"继续进行,好像什么也没发生",因为JVM(和各种库)将使用错误作为一种方式来表示"发生了一些非常严重的事情,我们需要尽快关闭".一般来说,最好在他们告诉你结束的时候听他们说.

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

也就是说,有一些极端情况是安全和/或希望捕获错误,或者至少是某些子类:

在某些情况下,您确实希望停止正常的流程:例如,如果您在Servlet中,您可能不希望Servlet运行器的默认异常处理程序向全世界宣布您有OutOfMemoryError,无论是不是你可以从它恢复.

有时,如果JVM可以从错误原因中干净地恢复,则会抛出错误.例如,如果在尝试分配数组时发生OutOfMemoryError,至少在Hotspot中,您似乎可以安全地从中恢复.(当然还有其他情况可能会抛出OutOfMemoryError而不能安全地尝试使用它.)

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

编辑:可能这很明显,但我忘了说在实践中,JVM实际上可能不会在Error上调用catch子句.我肯定看到Hotspot明显地掩盖了捕获某些OutOfMemoryErrors和NoClassDefFoundError的尝试.



3> Craig P. Mot..:

通常错误是您无法恢复的问题,例如OutOfMemoryError.通过捕获它们无关紧要,因此您通常应该让它们逃脱,并关闭虚拟机.


@ MetroidFan2002:在很多情况下你确实有足够的内存.例如,如果您想要将大文件加载到ram中,则分配可能会失败.然后,您可以以友好的方式通知用户.但在这种情况下,我建议捕获OutOfMemoryError而不是Throwable.

4> Darron..:

很多其他答案都是在狭隘地看待事物.

正如他们所说,如果你正在编写应用程序代码,你不应该抓住Throwable.你无法做任何事情,所以最好让周围的系统(JVM或框架)来处理这些问题.

但是,如果您正在编写"系统代码",如框架或其他低级代码,那么您可能非常希望捕获Throwable.原因是尝试在日志文件中报告异常.在某些情况下,您的日志记录将失败,但在大多数情况下,它将成功,您将获得解决问题所需的信息.完成日志记录后,应该重新抛出,终止当前线程或退出整个JVM.



5> Scott Stanch..:

我会走一条与其他人略有不同的路线。

在很多情况下,您想捕获Throwable(主要是记录/报告发生了恶事)。

但是,您需要小心并丢弃所有您无法处理的东西。

对于ThreadDeath尤其如此。

如果您遇到Throwable,请确保执行以下操作:

try {
    ...
} catch (SomeExceptionYouCanDoSomethingWith e) {
    // handle it
} catch (ThreadDeath t) {
    throw t;
} catch (Throwable t) {
    // log & rethrow
}

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有