java怎么捕获error,异常 - 何时捕获java.lang.Error?

异常 - 何时捕获java.lang.Error?

在什么情况下应该在应用程序上捕获java.lang.Error?

16个解决方案

95 votes

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

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

顺便说一下,我不确定从OutOfMemory恢复是不是可能。

Yoni Roit answered 2019-07-06T18:45:18Z

50 votes

决不。 您永远无法确定应用程序是否能够执行下一行代码。 如果您收到OutOfMemoryError,您无法保证能够可靠地执行任何操作。 捕获RuntimeException并检查异常,但绝不会出错。

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

tronda answered 2019-07-06T18:45:49Z

14 votes

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

例如,通常循环应该是:

try {

while (shouldRun()) {

doSomething();

}

}

catch (Throwable t) {

log(t);

stop();

System.exit(1);

}

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

Sarmun answered 2019-07-06T18:46:29Z

14 votes

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

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

您应该只捕获最高级别的Throwable。

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

最常见的错误是Throwable和NoClassDefFoundError,它们在大多数情况下都是运行时问题。

例如:

int length = Integer.parseInt(xyz);

byte[] buffer = new byte[length];

可以生成Throwable但它是运行时问题,没有理由终止您的程序。

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

我可以提供更多示例,说明为什么在顶层捕获Throwable并产生有用的错误消息是个好主意。

Horcrux7 answered 2019-07-06T18:47:42Z

8 votes

非常稀有。

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

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

Darron answered 2019-07-06T18:48:20Z

6 votes

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

nicerobot answered 2019-07-06T18:48:44Z

6 votes

通常不应该捕获Error,因为它表示应该永远不会发生的异常情况。

从Error类的Java API规范:

Error是Throwable的子类   这表明存在严重的问题   合理的申请不应该尝试   去抓。 大多数此类错误都是   异常情况。[...]

声明不需要方法   它的throws子句的任何子类   在期间可能抛出的错误   执行方法但不是   抓住了,因为这些错误是   不应该的异常情况   发生。

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

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

第11.5节“Java语言规范的例外层次结构”第2版中还有关于此主题的简短部分。

coobird answered 2019-07-06T18:49:47Z

6 votes

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

否则,请参阅其他答案。

noahlz answered 2019-07-06T18:50:20Z

5 votes

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

应用程序只有在必须清理时才应捕获此类的实例   异步终止后。 如果ThreadDeath被方法捕获,   重新抛出它以使线程实际死亡是很重要的。

Guillaume answered 2019-07-06T18:50:52Z

4 votes

很少,很少。

我只为一个非常具体的已知案例做过。例如,如果两个独立的ClassLoader加载相同的DLL,则可能抛出java.lang.UnsatisfiedLinkError。 (我同意我应该将JAR移动到共享的类加载器)

但最常见的情况是您需要登录才能知道用户投诉时发生了什么。 您希望向用户发送消息或弹出窗口,而不是默默地死亡。

即使是C / C ++中的程序员,他们也会弹出错误并告诉人们在退出之前不理解的东西(例如内存故障)。

Dennis C answered 2019-07-06T18:51:39Z

3 votes

在Android应用程序中,我正在捕获java.lang.VerifyError。 我正在使用的库不能在具有旧版操作系统的设备中工作,库代码会抛出这样的错误。 我当然可以通过在运行时检查OS的版本来避免错误,但是:

支持最旧的SDK可能会在将来针对特定库进行更改

try-catch错误块是更大的回退机制的一部分。 一些特定的设备,虽然它们应该支持该库,但会抛出异常。 我捕获VerifyError和所有异常以使用后备解决方案。

kgiannakakis answered 2019-07-06T18:52:19Z

3 votes

在测试环境中捕获java.lang.AssertionError非常方便...

Jono answered 2019-07-06T18:52:44Z

2 votes

理想情况下,我们不应该处理/捕获错误。 但根据框架或应用程序的要求,可能存在我们需要做的情况。 假设我有一个XML Parser守护程序,它实现了DOM Parser,它消耗更多内存。 如果有一个像Parser线程这样的要求在它出现OutOfMemoryError时不应该死掉,而是它应该处理它并向应用程序/框架的管理员发送消息/邮件。

user3510364 answered 2019-07-06T18:53:11Z

1 votes

理想情况下,我们永远不应该在Java应用程序中捕获Error,因为它是一种异常情况。 应用程序将处于异常状态,可能导致运行或出现严重错误的结果。

Vivek answered 2019-07-06T18:53:36Z

1 votes

在检查断言的单元测试中捕获错误可能是适当的。 如果有人禁用断言或以其他方式删除您想要知道的断言

Chanoch answered 2019-07-06T18:54:02Z

1 votes

当JVM不再按预期工作或接近时,会出现错误。 如果你发现错误,就不能保证catch块会运行,甚至不会保证它会一直运行到最后。

它还将取决于正在运行的计算机,当前的内存状态,因此无法测试,尝试并尽力而为。 你只会得到一个有害的结果。

您还将降低代码的可读性。

Nicolas Zozol answered 2019-07-06T18:54:41Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值