未经捕获的异常是如何在控制台输出的

512 阅读2分钟

未经捕获的异常是如何在控制台输出的?

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

未经捕获的异常是如何在控制台输出的?

执行下面这段代码:

package com.hawk.example.thread;
​
public class UncaughtExceptionTest {
    public static void main(String[] args) {
        System.out.println(1/0);
    }
}

控制台会有如下输出:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at com.hawk.example.thread.UncaughtExceptionTest.main(UncaughtExceptionTest.java:5)
​
Process finished with exit code 1

思考一下,我们的代码里没有捕获异常,控制台是如何输出异常信息的呢?

提示:既然我们的代码没有做处理,那么一定是执行在某个地方的一个方法来达到这个效果。

System.out.println(1/0);这一行打上断点,然后以debug方式启动,并且选择force step into进入

image-20221212203546074

最终来到了这一段代码

image-20221213092958561

看到红框框起来的地方了嘛,是不是很像控制台输出的内容。

test

可以看到,控制台的异常信息就是这里打印出来的。

Thread类的dispatchUncaughtException方法,所有未经捕获的异常都会被该方法捕获并输出至控制台中。

引申出来的问题

当我们的代码部署至服务器上时,我们一般都是通过日志文件来查看代码运行过程中出现的异常,但是当遇到未经捕获的异常时,如果我们没有做处理,那么这个异常信息就会被执行线程的dispatchUncaughtException方法吞掉,在日志文件中并不会打印出该异常信息。

解决方法

方案一

将所有的控制台输出转移输出到日志文件中。

方案二

Thread类提供了两个方法,来进行预处理,如下所示。

// 设置全局 UncaughtExceptionHandler
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh);
​
// 为当前 Thread 设置 UncaughtExceptionHandler
public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh);
​

示例如下:

image-20221213103647199

推荐方案二。