这篇文章主要介绍了JAVA如何处理未捕获异常,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
成都创新互联-专业网站定制、快速模板网站建设、高性价比友好网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式友好网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖友好地区。费用合理售后完善,十年实体公司更值得信赖。
JVM为我们提供了线程的未捕获异常处理机制,通过Thread的setUncaughtExceptionHandler方法:
public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)
可以设置当前线程的未捕获异常处理器。如下面的例子就通过设置uncaughtExceptionHandler成功捕获到了除0异常:
public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new UncaughtException.Run());
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {@Override
br/>@Override
System.out.println("runnable run---------------");
int i = 1/0;
}
}
结果:
runnable run---------------
uncaughtExceptionHandler catch a Exception---------
/ by zero
线程出现未捕获异常后,JVM将调用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);
}
方法的描述已经清楚地说明了这个方法只是提供给JVM调用的,getUncaughtExceptionHandler方法并没有简单返回设置好的uncaughtExceptionHandler:
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return uncaughtExceptionHandler != null ?
uncaughtExceptionHandler : group;
}
可见,如果没有设置uncaughtExceptionHandler,将使用线程所在的线程组来处理这个未捕获异常。线程组ThreadGroup实现了UncaughtExceptionHandler,所以可以用来处理未捕获异常。ThreadGroup类定义:
class ThreadGroup implements Thread.UncaughtExceptionHandler
ThreadGroup实现的uncaughtException如下:
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);
}
}
}
默认情况下,线程组处理未捕获异常的逻辑是,首先将异常消息通知给父线程组,然后尝试利用一个默认的defaultUncaughtExceptionHandler来处理异常,如果没有默认的异常处理器则将错误信息输出到System.err。也就是JVM提供给我们亨达返佣www.fx61.com/brokerlist/HantecGlobal.html设置每个线程的具体的未捕获异常处理器,也提供了设置默认异常处理器的方法。
设置了默认的异常处理器后,系统中所有未直接设置异常处理器的线程将使用这个默认的异常处理器。
public void defaultWay(){
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {@Override
br/>@Override
int i = 1/0;
}
}, "thread1").start();
new Thread(myGroup, new Runnable() {@Override
br/>super(name);
}
@Override
System.out.println("I am a bad group and do nothing");
}
}
如果使用了BadGroup得出结果将是打印两条I am a bad group and do nothing。
上面的例子中,不论是ThreadGroup或者BadGroup都主动的给线程设置了线程组,那么如果不给线程设置线程组会怎么样呢?还会正常的使用默认异常处理器吗?这些跟线程组的来源相关,先看一个例子:
public void mainGroup() throws InterruptedException {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {@Override
br/>@Override
System.out.println(Thread.currentThread().getName() + " said my thread group is " + Thread.currentThread().getThreadGroup().getName());
new Thread(new Runnable() {@Override
br/>@Override
System.out.println("捕获异常处理方法:" + e);
}
}
我们有三种方式使用该线程异常捕获器:
1、在创建线程的时候进行设置
Thread t = new Thread(new ExceptionThread());
t.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
t.start();
2、使用Executors创建线程时,还可以在TreadFactory中设置
ExecutorService exec = Executors.newCachedThreadPool(new ThreadFactory(){@Override
br/>@Override
Thread thread = newThread(r);
thread.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
return thread;
}
});
exec.execute(new ExceptionThread());
3、如果我们只需要一个线程异常处理器处理线程的异常,那么我们可以设置一个默认的线程异常捕获器,当线程出现异常时,
如果我们没有指定线程的异常捕获器,而且线程组也没有设置(线程组不用考虑,因为这是一个不成功的尝试),那么就会使用
默认的线程异常捕获器。
// 设置默认的线程异常捕获处理器
Thread.setDefaultUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
通过以上方法就可以捕获并处理线程的异常了。
感谢你能够认真阅读完这篇文章,希望小编分享的“JAVA如何处理未捕获异常”这篇文章对大家有帮助,同时也希望大家多多支持创新互联,关注创新互联行业资讯频道,更多相关知识等着你来学习!