1

我知道这ErrorThrowable(因此可以处理)并且Error处理不是最佳实践,但假设我们需要全部捕获Error

一般有可能吗?我的意思是可能出现在守护线程中的错误呢?他们会崩溃 jvm 而我不知道。

Error即使我用 try-catch 包围 main(String... args) 我还能错过吗?

4

3 回答 3

5

您可以通过Thread.setUncaughtExceptionHandler()捕获未捕获的异常

设置当线程由于未捕获的异常而突然终止时调用的默认处理程序,并且没有为该线程定义其他处理程序。

未捕获的异常处理首先由线程控制,然后由线程的 ThreadGroup 对象控制,最后由默认的未捕获异常处理程序控制。如果线程没有明确的未捕获异常处理程序集,并且线程的线程组(包括父线程组)没有专门化其 uncaughtException 方法,则将调用默认处理程序的 uncaughtException 方法。

这是否是一个好主意是另一个问题(!)。您可能只是想清理资源、关闭连接等、记录问题和/或提醒用户。如果您确实有类似OutOfMemoryErrors的关键问题,那么您无能为力。

于 2013-08-28T10:33:21.150 回答
1

Error 是 Throwable 的子类,表示合理的应用程序不应尝试捕获的严重问题。大多数此类错误是异常情况。

现在,由于 Error 确实扩展了 Throwable,因此可以通过一个简单的 try-catch 语句捕获“任何”错误,如下所示:

try{
    //Error causing code here...
}catch(Error e){
    //Handle error here...
}

但是,由于错误以不同的形式出现,抛出的错误可能会也可能不会伴随 jvm 行为的变化而导致意外结果。

考虑错误 OutOfMemoryError。抛出此错误时,JVM 的堆可能已满,以至于任何类型的处理代码都会导致另一个 OutOfMemoryError 被抛出,从而使任何恢复尝试无效。

此外,即使在“主”线程(应用程序启动的线程)上运行时,错误也可能导致 JVM 在每次抛出错误之前崩溃。

查看 VirtualMachineError 的描述(OutOfMemoryError、StackOverflowError、InternalError 等 Errors 是其子类)我们看到:

抛出以指示 Java 虚拟机已损坏或已用完继续运行所需的资源。

javadoc 本身指出 jvm 不再可以正常继续运行,更不用说允许程序员“处理”它们了。

另一方面,诸如 UnsatisfiedLinkError 之类的错误通常不会立即导致 jvm 出现问题,并且通常可以处理(这是否是好的做法值得商榷)。我个人曾经使用过一个涉及处理 UnsatisfiedLinkError 的结构来确定要为 JNI 加载的正确库。

现在,可以处理所有错误吗?理论上是的,如果我们假设 JVM 可以完美地继续运行,尽管声称已经发生了致命的失败......在这方面,实际上只有一小部分错误是可以处理的。是否应该处理这些小的错误子集也是一个极具争议的话题。

于 2013-08-28T10:58:05.067 回答
0

你可以处理异常,但你不能处理错误。

于 2013-08-28T10:34:33.913 回答