Thread.UncaughtException接口

这篇博客详细探讨了Thread.UncaughtException接口在Java中的作用,如何使用它来捕获并处理未被捕获的异常,以此防止系统崩溃。通过实例分析,解释了在异常处理中的关键点和最佳实践。

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

import java.lang.Thread.UncaughtExceptionHandler;

/**
 * Thread.UncaughtExceptionHandler的用法
 */
class CrashHandler implements UncaughtExceptionHandler {
	public CrashHandler() {

	}

	@Override
	public void uncaughtException(Thread t, Throwable e) {
		System.out.println("系统崩溃了");
	}

}

public class UncaughtExceptionHandlerDemon {
	public static void main(String[] args) {
		Thread.currentThread().setUncaughtExceptionHandler(new CrashHandler());
		if (args != null)
			throw new NullPointerException("你妈");
		System.out.println("======");
	}
}
 

运行结果:系统崩溃了


import java.lang.Thread.UncaughtExceptionHandler;

/**
 * Thread.UncaughtExceptionHandler的用法
 */
class CrashHandler implements UncaughtExceptionHandler {
	public CrashHandler() {

	}

	@Override
	public void uncaughtException(Thread t, Throwable e) {
		System.out.println("系统崩溃了");
	}

}

public class UncaughtExceptionHandlerDemon {
	public static void main(String[] args) {
		Thread.setDefaultUncaughtExceptionHandler(new CrashHandler());
		if (args != null)
			throw new NullPointerException("你妈");
		System.out.println("======");
	}
}


 

运行结果:系统崩溃了

这两者的区别是什么呢??

Thread.UncaughtExceptionHandler的API解释:

Interface for handlers invoked when a Thread abruptly terminates due to an uncaught exception.

When a thread is about to terminate due to an uncaught exception the Java Virtual Machine will query the thread for itsUncaughtExceptionHandler usinggetUncaughtExceptionHandler and will invoke the handler'suncaughtException method, passing the thread and the exception as arguments. If a thread has not had itsUncaughtExceptionHandler explicitly set, then itsThreadGroup object acts as itsUncaughtExceptionHandler. If theThreadGroup object has no special requirements for dealing with the exception, it can forward the invocation to thedefault uncaught exception handler.

简单翻译一下,不好的地方请大家指教:

  一个处理接口,当一个线程因为没有捕捉的异常导致的突然终止时,该接口被唤醒。

 当一个线程因为不能捕捉的异常将要终止的时候,JVM会调用getUncaughtExceptionHandler方法查找扎个线程对应的指定UncaughtExceptionHandler对象,并且回调这个对象的uncaughtException方法。如果这个线程没有指定的UncaughtExceptionHandler对象,那么将ThreadGroup对象作为UncaughtExceptionHandler对象,因为ThreadGroup类实现了Thread.UncaughtExceptionHandler接口;会调用顶层ThreadGroup的那个默认的UncaughtExceptionHandler对象的uncaughtException方法。

这个过程对应的源代码:

1、当发生异常的时候,比如调用 throw  new  Exception()没有捕获,进入产生异常的线程(Thread类)的dispatchUncaughtException方法

 /**
     * 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);
    }

2、getUncaughtExceptionHandler方法如下:

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

其中uncaughtExceptionHandler是UncaughtExceptionHandler的对象,而group是ThreadGroup的对象。

3、如果我们通过public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)方法来设置指定的

UncaughtExceptionHandler对象,就直接调用这个的UncaughtExceptionHandler的uncaughtException方法,JVM退出。

4、如果我们没有通过public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)方法来设置指定的

UncaughtExceptionHandler对象,因为只是唯一的设置方式,在Thread类里面也没有给它赋值,所以为空,那么调用group的uncaughtException方法,因为ThreadGroup实现了UncaughtExceptionHandler接口

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

这是ThreadGroup类中的code,其中parent是ThreadGroup的对象,也就是说ThreadGroup中还可以有ThreadGroup对象,

程序会先找到顶层的ThreadGroup对象。直接进入else分支,如果设置了默认的UncaughtExceptionHandler对象,那么调用默认的UncaughtExceptionHandler对象的uncaughtException方法,JVM退出。如果没有设置默认的UncaughtExceptionHandler对象,那么就打印出异常信息,最后虚拟机会退出。

这里调用的优先级是:指定的UncaughtExceptionHandler-----》ThreadGroup的默认的UncaughtExceptionHandler

注意:我们将产生的异常对象提交给了运行时环境,这个过程叫抛出异常,运行时环境将寻找对应的catch块,找到了合适的catch块,就将这个异常对象提交给catch块,这个过程叫捕捉异常,如果没有找到合适的catch块,那么运行时环境将异常对象提交给JVM,JVM得到这个异常对象后,找到产生异常的线程对应的UncaughtExceptionHandler对象,回调uncaughtException方法,然后JVM退出。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值