Thread.UncaughtExceptionHandler
表示当处理未捕获异常的方法本身抛出异常时,该异常将被忽略:
void uncaughtException (线程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
来验证了这一点,但我仍然得到了#34;红色"输出:
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上测试stacktrace颜色(df.java:13)
异常:从线程" main"
中的UncaughtExceptionHandler抛出java.lang.RuntimeException
这些现象的解释是什么?
UncaughtExceptionHandler中抛出的错误会发生什么?预期(记录或保证)的行为是什么?
答案 0 :(得分:5)
HotSpot JVM打印从UncaughtExceptionHandler抛出的异常。 见JavaThread::exit
if (HAS_PENDING_EXCEPTION) {
ResourceMark rm(this);
jio_fprintf(defaultStream::error_stream(),
"\nException: %s thrown from the UncaughtExceptionHandler"
" in thread \"%s\"\n",
pending_exception()->klass()->external_name(),
get_thread_name());
CLEAR_PENDING_EXCEPTION;
}
JVM直接在stderr
上打印这些异常,无论System.err
状态如何 - 是否被重定向。
嗯,这种警告不会影响应用程序 - 在这个意义上,例外是"忽略"。但你是对的,这种行为并不明显。 Javadoc具有误导性,最好修复。
答案 1 :(得分:2)
忽略异常,并且在从非主线程抛出时继续处理。
如果它在main中抛出,则返回的错误代码为非零。
通过syserr记录未处理的异常。
public static void main(final String[] args) {
final Thread myThread = new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread()
.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread t, final Throwable e) {
System.out.println("In child UncaughtExceptionHandler at " + java.time.Instant.now());
throw new RuntimeException("From child thread UncaughtExceptionHandler"
+ java.time.Instant.now());
}
});
throw new RuntimeException("from runnable");
}
});
Thread.currentThread()
.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread t, final Throwable e) {
System.out.println("In main UncaughtExceptionHandler " + java.time.Instant.now());
throw new RuntimeException("From main thread UncaughtExceptionHandler" + java.time.Instant.now());
}
});
myThread.start();
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));
System.out.println("After child thread: " + java.time.Instant.now());
//Will result in a non-zero return code
throw new RuntimeException("from main");
}
<强>输出:强>
在2014-07-19T04:10:46.184Z的子UncaughtExceptionHandler中
异常:从线程“Thread-0”中的UncaughtExceptionHandler抛出java.lang.RuntimeException 子线程后:2014-07-19T04:10:48.197Z 在主UncaughtExceptionHandler中2014-07-19T04:10:48.197Z
异常:从线程“main”中的UncaughtExceptionHandler抛出java.lang.RuntimeException