溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JAVA如何處理未捕獲異常

發(fā)布時(shí)間:2021-11-24 09:30:06 來源:億速云 閱讀:227 作者:小新 欄目:編程語(yǔ)言

這篇文章主要介紹了JAVA如何處理未捕獲異常,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。


   JVM為我們提供了線程的未捕獲異常處理機(jī)制,通過Thread的setUncaughtExceptionHandler方法:
               public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)
   可以設(shè)置當(dāng)前線程的未捕獲異常處理器。如下面的例子就通過設(shè)置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;
}
}
結(jié)果:
runnable run---------------
uncaughtExceptionHandler catch a Exception---------
/ by zero
     線程出現(xiàn)未捕獲異常后,JVM將調(diào)用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);
    }
        方法的描述已經(jīng)清楚地說明了這個(gè)方法只是提供給JVM調(diào)用的,getUncaughtExceptionHandler方法并沒有簡(jiǎn)單返回設(shè)置好的uncaughtExceptionHandler:
    public UncaughtExceptionHandler getUncaughtExceptionHandler() {
    return uncaughtExceptionHandler != null ?
    uncaughtExceptionHandler : group;
    }
       可見,如果沒有設(shè)置uncaughtExceptionHandler,將使用線程所在的線程組來處理這個(gè)未捕獲異常。線程組ThreadGroup實(shí)現(xiàn)了UncaughtExceptionHandler,所以可以用來處理未捕獲異常。ThreadGroup類定義:
    class ThreadGroup implements Thread.UncaughtExceptionHandler
       ThreadGroup實(shí)現(xiàn)的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);
      }
      }
      }
           默認(rèn)情況下,線程組處理未捕獲異常的邏輯是,首先將異常消息通知給父線程組,然后嘗試?yán)靡粋€(gè)默認(rèn)的defaultUncaughtExceptionHandler來處理異常,如果沒有默認(rèn)的異常處理器則將錯(cuò)誤信息輸出到System.err。也就是JVM提供給我們亨達(dá)返傭www.fx61.com/brokerlist/HantecGlobal.html設(shè)置每個(gè)線程的具體的未捕獲異常處理器,也提供了設(shè)置默認(rèn)異常處理器的方法。
           設(shè)置了默認(rèn)的異常處理器后,系統(tǒng)中所有未直接設(shè)置異常處理器的線程將使用這個(gè)默認(rèn)的異常處理器。
      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得出結(jié)果將是打印兩條I am a bad group and do nothing。
         上面的例子中,不論是ThreadGroup或者BadGroup都主動(dòng)的給線程設(shè)置了線程組,那么如果不給線程設(shè)置線程組會(huì)怎么樣呢?還會(huì)正常的使用默認(rèn)異常處理器嗎?這些跟線程組的來源相關(guān),先看一個(gè)例子:
      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、在創(chuàng)建線程的時(shí)候進(jìn)行設(shè)置
      Thread t = new Thread(new ExceptionThread());
      t.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
      t.start();
      2、使用Executors創(chuàng)建線程時(shí),還可以在TreadFactory中設(shè)置
      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、如果我們只需要一個(gè)線程異常處理器處理線程的異常,那么我們可以設(shè)置一個(gè)默認(rèn)的線程異常捕獲器,當(dāng)線程出現(xiàn)異常時(shí),
            如果我們沒有指定線程的異常捕獲器,而且線程組也沒有設(shè)置(線程組不用考慮,因?yàn)檫@是一個(gè)不成功的嘗試),那么就會(huì)使用
           默認(rèn)的線程異常捕獲器。
      // 設(shè)置默認(rèn)的線程異常捕獲處理器
      Thread.setDefaultUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
      通過以上方法就可以捕獲并處理線程的異常了。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“JAVA如何處理未捕獲異?!边@篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI