温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

JAVA如何处理未捕获异常

发布时间:2021-11-24 09:30:06 来源:亿速云 阅读:217 作者:小新 栏目:编程语言

这篇文章主要介绍了JAVA如何处理未捕获异常,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。


   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<br/public void run() {
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<br/public void run() {
      int i = 1/0;
      }
      }, "thread1").start();
      new Thread(myGroup, new Runnable() {@Override
      br/>super(name);
      }
      @Override<br/public void uncaughtException(Thread t, Throwable e) {
      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<br/public void run() {
      System.out.println(Thread.currentThread().getName() + " said my thread group is " + Thread.currentThread().getThreadGroup().getName());
      new Thread(new Runnable() {@Override
      br/>@Override<br/public void uncaughtException(Thread t, Throwable e) {
      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/" rel="nofollow">br/>@Override<br/            public Thread newThread(Runnable r) {
                      Thread thread = newThread(r);
                      thread.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
                      return thread;
                  }
      });
      exec.execute(new ExceptionThread());
      3、如果我们只需要一个线程异常处理器处理线程的异常,那么我们可以设置一个默认的线程异常捕获器,当线程出现异常时,
            如果我们没有指定线程的异常捕获器,而且线程组也没有设置(线程组不用考虑,因为这是一个不成功的尝试),那么就会使用
           默认的线程异常捕获器。
      // 设置默认的线程异常捕获处理器
      Thread.setDefaultUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
      通过以上方法就可以捕获并处理线程的异常了。

感谢你能够认真阅读完这篇文章,希望小编分享的“JAVA如何处理未捕获异常”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI