是否吞噬了UncaughtExceptionHandler中抛出的错误? [英] Do errors thrown within UncaughtExceptionHandler get swallowed?

查看:198
本文介绍了是否吞噬了UncaughtExceptionHandler中抛出的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Thread.UncaughtExceptionHandler 指出当处理未捕获异常的方法本身抛出异常时,该异常将被忽略:

Thread.UncaughtExceptionHandler states that when the method which handles uncaught exceptions itself throws an exception, that exception will be ignored:


void uncaughtException (线程t,Throwable e):

void uncaughtException(Thread t, Throwable e):

给定线程由于给定的
未捕获异常而终止时调用的方法。

Method invoked when the given thread terminates due to the given uncaught exception.

Java将忽略此方法抛出的任何异常
虚拟机。

但是当我测试它时,JVM没有忽略由处理的异常未捕获的异常处理程序`:

However when I tested it, the JVM did not ignore the exceptions handled by the uncaught exception handler`:

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):

Eclipse Console output (JRE 1.7):


异常:从线程main中的
UncaughtExceptionHandler抛出java.lang.RuntimeException

Exception: java.lang.RuntimeException thrown from the UncaughtExceptionHandler in thread "main"

我发现的另一个奇怪的是我得到的输出不是来自 System.err 。它似乎完全来自另一个流。我通过将 System.err 重定向到 System.out 来验证这一点,但我仍然得到红色输出:

Another oddity I found out is that the output I get isn't coming from System.err. It seems to be from another stream altogether. I verified this by redirecting System.err to System.out, but I'm still getting "red" output:

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");
}

输出(粗体表示红色):

The output (bolded signifies red color):


true

true

这是黑色

java.lang.Error:在asf.df.main上测试stacktrace颜色(df.java:13)

java.lang.Error: test stacktrace color at asf.df.main(df.java:13)

异常:抛出java.lang.RuntimeException线程main中的UncaughtExceptionHandler

这些现象的解释是什么?

What's the explanation for these phenomenons?

UncaughtExceptionHandler中抛出的错误会怎样?预期(记录或保证)行为是什么?

What happens to errors thrown within UncaughtExceptionHandler? What's the expected (documented or guaranteed) behavior?

推荐答案

HotSpot JVM打印从UncaughtExceptionHandler抛出的异常。
参见 JavaThread :: exit

HotSpot JVM prints the exceptions thrown from the UncaughtExceptionHandler. See 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 状态 - 是否被重定向。

JVM prints these exceptions itself directly on stderr regardless of the System.err state - whether it was redirected or not.

嗯,这种警告不会影响应用程序 - 在这个意义上,异常被忽略。但你是对的,这种行为并不明显。 Javadoc具有误导性,最好修复。

Well, this kind of warning does not affect the application - in this sense the exception is "ignored". But you are right, this behavior is not obvious. Javadoc is misleading and is better to be fixed.

这篇关于是否吞噬了UncaughtExceptionHandler中抛出的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆