JVM异常处理小分析

本文详细介绍了Java中未捕获异常的处理方式,当trycatch未处理异常时,JVM如何调用私有方法dispatchUncaughtException进行处理,并通过源码分析展示了异常堆栈信息的打印过程。同时,提供了设置自定义UncaughtExceptionHandler的示例,当线程发生异常时,如何自定义输出异常信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可能平时朋友们都好奇,为什么没有进行try catch的处理,当我们抛出异常时还是能打印出异常堆栈信息:

    public static void main(String[] args) throws Exception {
       throw new RuntimeException("error");
    }

在这里插入图片描述

其实通过debug,可以发现线程会执行如下方法, 通过注释可以知道,当异常未被代码捕获时,jvm会调用该方法来对异常进行处理。

    /**
     * Dispatch an uncaught exception to the handler. This method is
     * intended to be called only by the JVM.
     */
    private void dispatchUncaughtException(Throwable e) {
        getUncaughtExceptionHandler().uncaughtException(this, e);
    }

首先进入getUncaughtExceptionHandler()方法

  private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
	private ThreadGroup group;

	public UncaughtExceptionHandler getUncaughtExceptionHandler() {
        return uncaughtExceptionHandler != null ?
            uncaughtExceptionHandler : group;
    }

该方法会进行判断,若设置了uncaughtExceptionHandler,则使用uncaughtExceptionHandler的uncaughtException()方法,否则使用

group的。

而我们可以通过如下方法来为线程设置该Handler。

Thread.currentThread().setUncaughtExceptionHandler();

然后我们再看uncaughtException()方法,若我们没有设置handler,则使用ThreadGroup的方法。

    public void uncaughtException(Thread t, Throwable e) {
        if (parent != null) {
            parent.uncaughtException(t, e);
        } else {
            Thread.UncaughtExceptionHandler ueh =
                Thread.getDefaultUncaughtExceptionHandler();
            if (ueh != null) {
                ueh.uncaughtException(t, e);
            } else if (!(e instanceof ThreadDeath)) {
                System.err.print("Exception in thread \""
                                 + t.getName() + "\" ");
                e.printStackTrace(System.err);
            }
        }
    }

通过源码可以发现, 当!(e instanceof ThreadDeath)时,将异常堆栈信息输出到控制台上,于是谜底揭晓!

---------------------------------------------------------------------------分割线----------------------------------------------------------------------------------------------------

使用自定义的UncaughtExceptionHandler的小demo

    public static void main(String[] args) throws Exception {
       Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
           @Override
           public void uncaughtException(Thread t, Throwable e) {
               System.out.println("线程" + t.getName() + "发生异常");
               System.out.println(e.toString());
               System.out.println("异常类型为:" + e.getClass());
           }
       });
       throw new RuntimeException("error");
    }

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值