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

何时捕获java.lang.Error?

如何解决《何时捕获java.lang.Error?》经验,为你挑选了9个好方法。

在什么情况下应该抓住java.lang.Error应用程序?



1> Yoni Roit..:

一般来说,从不.但是,有时您需要捕获特定的错误.

如果您正在编写框架代码(加载第三方类),那么捕获LinkageErrors(没有发现类def,不满意的链接,不兼容的类更改)可能是明智的.我也看到一些愚蠢的第三方代码抛出错误的子句,所以你也必须处理它们.

顺便说一句,我不确定从OutOfMemory恢复是不可能的.


捕获OutOfMemoryError有时是有意义的 - 例如,当您创建大型数组列表时.
我必须完全加载DLL,如果没有正确配置将失败.在此应用程序的情况下不是致命错误.
@SpaceTrucker:这种方法在多线程应用程序中是否运行良好,或者是否存在因其而导致其他线程中较小分配失败的重大风险?...大概只有你的阵列只是小到可以分配,但没有留下任何其他人.

2> tronda..:

决不.您永远无法确定应用程序是否能够执行下一行代码.如果你得到了OutOfMemoryError,你无法保证你能够可靠地做任何事情.捕获RuntimeException并检查异常,但从不出错.

http://pmd.sourceforge.net/rules/strictexception.html


永远不要把话说绝了.我们有测试代码执行"断言错误"; 然后捕获AssertionError以确保设置了-ea标志.除此之外......是的,可能永远不会;-)
从来没有......除非你绝对需要.永远不是一个强有力的词,规则总是有例外.如果您正在构建一个框架,那么即使它只是为了记录,您也不一定要抓住并处理某些错误.
将请求交给工作线程的服务器应用程序怎么样?可能在工作线程上捕获Throwable以捕获任何错误是没有意义的,并且至少尝试并记录出错的地方?

3> Horcrux7..:

通常,您应始终捕获java.lang.Error并将其写入日志或将其显示给用户.我支持并且每天都看到程序员无法分辨程序中发生了什么.

如果你有一个守护程序线程,那么你必须防止它被终止.在其他情况下,您的应用程序将正常工作

你应该只抓到java.lang.Error最高级别.

如果查看错误列表,您会发现大多数错误都可以处理.例如ZipError,在读取损坏的zip文件时会出现a .

最常见的错误是OutOfMemoryErrorNoClassDefFoundError,这两者都是在大多数情况下运行时的问题.

例如:

int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];

可以生成一个,OutOfMemoryError但它是一个运行时问题,没有理由终止你的程序.

NoClassDefFoundError如果库不存在或者您使用其他Java版本,则主要发生.如果它是您程序的可选部分,那么您不应该终止您的程序.

我可以提供更多的例子,说明为什么抓住Throwable顶层并产生有用的错误信息是一个好主意.


一般来说,在顶级捕获`java.lang.Error`或`java.lang.Throwable`并尝试对它做一些事情可能会有所帮助 - 比如记录一条错误消息.但在那时,无法保证这将被执行.如果您的JVM是OOMing,尝试记录可能会分配更多`String`s,它会触发另一个OOM.

4> Sarmun..:

在多线程环境中,您最常想要抓住它!当你抓住它,记录它,并终止整个应用程序!如果你不这样做,一些可能正在做一些关键部分的线程将会死亡,应用程序的其余部分会认为一切正常.除此之外,许多不必要的情况都可能发生.一个最小的问题是,如果其他线程由于一个线程不起作用而开始抛出一些异常,那么您将无法轻松找到问题的根.

例如,通常循环应该是:

try {
   while (shouldRun()) {
       doSomething();
   }
}
catch (Throwable t) {
   log(t);
   stop();
   System.exit(1);
}

即使在某些情况下,您也希望以不同的方式处理不同的错误,例如,在OutOfMemoryError上,您可以定期关闭应用程序(甚至可能释放一些内存,并继续),在其他一些情况下,您可以做的事情并不多.



5> Darron..:

非常稀有.

我只说在一个线程的顶层,以便尝试发出一条消息,其中包含线程死亡的原因.

如果您处于为您执行此类操作的框架中,请将其保留在框架中.



6> nicerobot..:

几乎从不.错误旨在成为应用程序通常无法执行任何操作的问题.唯一的例外可能是处理错误的呈现,但即使这可能不会按计划进行,具体取决于错误.



7> coobird..:

一个Error通常不应该被捕获,因为它表明绝不应该出现的异常情况.

从类的Java API规范Error:

An Error是一个子类Throwable ,表示合理的应用程序不应该试图捕获的严重问题.大多数此类错误都是异常情况.[...]

一个方法不需要在其throws子句中声明在执行方法期间可能抛出但未捕获的任何Error类,因为这些错误是永远不应发生的异常情况.

正如规范所提到的那样,Error只有在机会Error出现的情况下,才会抛出,应用程序可以做的很少,并且在某些情况下,Java虚拟机本身可能处于不稳定状态(例如VirtualMachineError)

虽然a Error是一个子类Throwable,意味着它可以被一个try-catch子句捕获,但它可能并不真正需要,因为当ErrorJVM抛出一个应用程序时,应用程序将处于异常状态.

第11.5节" Java语言规范的异常层次 " ,第2版中还有一个关于此主题的简短部分.



8> noahlz..:

如果你疯狂到创建一个新的单元测试框架,你的测试运行器可能需要捕获任何测试用例抛出的java.lang.AssertionError.

否则,请参阅其他答案.



9> Guillaume..:

还有一些其他情况,如果你发现错误,你必须重新抛出它.例如,永远不应该捕获ThreadDeath,如果你在一个包含的环境(如应用服务器)中捕获它,它可能会导致很大的问题:

只有在异步终止后必须清理的情况下,应用程序才应捕获此类的实例.如果ThreadDeath被一个方法捕获,重要的是它被重新抛出,以便线程实际死亡.


这实际上是一个非问题,因为你只是做*不*抓住`Error`s.
推荐阅读
地之南_816
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有