【发布时间】:2014-07-18 22:27:39
【问题描述】:
Thread.UncaughtExceptionHandler 声明当处理未捕获异常的方法本身抛出异常时,该异常将被忽略:
void uncaughtException(Thread t, Throwable e):
当给定线程由于给定而终止时调用的方法 未捕获的异常。
此方法抛出的任何异常都将被 Java 忽略 虚拟机。
但是当我测试它时,JVM并没有忽略未捕获的异常处理程序处理的异常:
public static void main(final String args[]) {
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread arg0, Throwable arg1) {
throw new java.lang.RuntimeException("e2");
}
});
throw new RuntimeException("e1");
}
Eclipse 控制台输出 (JRE 1.7):
异常:java.lang.RuntimeException 从 线程“main”中的 UncaughtExceptionHandler
我发现的另一个奇怪之处是我得到的输出不是来自System.err。它似乎完全来自另一个流。我通过将System.err 重定向到System.out 验证了这一点,但我仍然得到“红色”输出:
public static void main(final String[] args) {
System.setErr(System.out);
System.out.println(System.err == System.out);
System.err.println("this is black color");
try {
throw new Error("test stacktrace color");
} catch (Throwable e) {
e.printStackTrace();
}
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
throw new RuntimeException("from handler");
}
});
throw new RuntimeException("from main");
}
输出(粗体表示红色):
是的
这是黑色
java.lang.Error:在 asf.df.main(df.java:13) 处测试堆栈跟踪颜色
异常:从线程“main”中的 UncaughtExceptionHandler 抛出 java.lang.RuntimeException
这些现象的解释是什么?
UncaughtExceptionHandler 中抛出的错误会发生什么?预期(记录或保证)的行为是什么?
【问题讨论】:
-
可能特定于版本?
-
即使在以前的 Java 版本中,文档也声明它应该被 JVM 忽略。
-
在 Oracle "1.6.0_39" / Ubuntu 12.04 中,未捕获的异常处理程序中抛出的异常被 JVM 吞噬。就像@Andrew_CS 所说,它可能是特定于版本/供应商的。
-
定义“没有忽略”。它可能会打印堆栈跟踪,但不会退出调用这些方法的线程,就像 Swing 事件线程捕获、打印和忽略 RTE 而不是退出一样。
-
@EJP, "ignore" 是文档使用的关键字。他们没有定义它,但从我得到的输出来看,它可能“没有被忽略”。
标签: java exception-handling jvm uncaught-exception uncaughtexceptionhandler