未经捕获的异常是如何在控制台输出的?
本文已参与「新人创作礼」活动,一起开启掘金创作之路。
未经捕获的异常是如何在控制台输出的?
执行下面这段代码:
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进入
最终来到了这一段代码
看到红框框起来的地方了嘛,是不是很像控制台输出的内容。
可以看到,控制台的异常信息就是这里打印出来的。
即Thread类的dispatchUncaughtException方法,所有未经捕获的异常都会被该方法捕获并输出至控制台中。
引申出来的问题
当我们的代码部署至服务器上时,我们一般都是通过日志文件来查看代码运行过程中出现的异常,但是当遇到未经捕获的异常时,如果我们没有做处理,那么这个异常信息就会被执行线程的dispatchUncaughtException方法吞掉,在日志文件中并不会打印出该异常信息。
解决方法
方案一
将所有的控制台输出转移输出到日志文件中。
方案二
Thread类提供了两个方法,来进行预处理,如下所示。
// 设置全局 UncaughtExceptionHandler
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh);
// 为当前 Thread 设置 UncaughtExceptionHandler
public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh);
示例如下:
推荐方案二。