我知道Error
是Throwable
(因此可以处理)并且Error
处理不是最佳做法,但假设我们需要捕获所有Error
。
一般情况下可能吗?我是说可以出现在守护程序线程中的错误呢?他们将崩溃jvm,我不会知道它。
即使我用try-catch包围main(String ... args),我还能错过Error
吗?
答案 0 :(得分:5)
您可以通过Thread.setUncaughtExceptionHandler()
捕捉未捕获的例外情况设置当线程突然终止到期时调用的默认处理程序 到未捕获的异常,并没有为其定义其他处理程序 那个帖子。
未捕获的异常处理首先由线程控制,然后由 线程的ThreadGroup对象,最后是默认的未捕获对象 异常处理程序如果线程没有明确的未捕获 异常处理程序集和线程的线程组(包括父级 然后,线程组)不专门化它的uncaughtException方法 将调用默认处理程序的uncaughtException方法。
这是一个好主意是另一个问题(!)。可能您只是想清理资源,关闭连接等,记录问题和/或提醒用户。如果您确实遇到了OutOfMemoryErrors
等关键问题,那么您可以做其他事情。
答案 1 :(得分:1)
错误是Throwable的子类,表示合理的应用程序不应该尝试捕获的严重问题。大多数此类错误都是异常情况。
现在,由于Error确实扩展了Throwable,因此可以通过简单的try-catch语句捕获“any”错误,如下所示:
try{
//Error causing code here...
}catch(Error e){
//Handle error here...
}
但是,由于错误的形式不同,抛出的错误可能会或可能不会伴随jvm行为的变化而导致意外结果。
考虑Error OutOfMemoryError。抛出此错误时,JVM的堆可能已满,任何类型的处理代码都会导致抛出另一个OutOfMemoryError,从而导致任何恢复尝试失效。
此外,即使在“主”线程(应用程序启动的线程)上运行时,错误也可能导致JVM在每次抛出错误之前崩溃。
查看VirtualMachineError的描述(其中包括错误,如OutOfMemoryError,StackOverflowError,InternalError等是其子类),我们看到:
抛出此异常表示Java虚拟机已损坏或已耗尽其继续运行所需的资源。
javadoc本身表明jvm不再能够继续正常运行,更不用说让程序员“处理”它们了。
另一方面,诸如UnsatisfiedLinkError之类的错误通常不会立即引起jvm的问题,并且通常可以处理(这是否是好的做法是有争议的)。我个人曾经使用过涉及处理UnsatisfiedLinkError的结构来确定要为JNI加载的正确库。
现在,是否可以处理所有错误?理论上是的,如果我们假设JVM可以继续完美运行,尽管声称已经致命失败......就此而言,实际上只有一小部分错误可以处理。是否应该处理这些小的错误子集也是一个备受争议的话题。
答案 2 :(得分:0)
您可以处理异常,但无法处理错误。