關於UncaughtException

關於UncaughtException
java

問1:
以下代碼 ide

try {
//代碼塊
} catch (Throwable e) {
e.printStackTrace();
}

能夠捕獲代碼塊中的全部exception嗎?
答:不是,當代碼塊調用子線程執行時候報錯的時候,run方法內拋出的異常(前提是run內部未捕獲)。
緣由:run方法是不拋出任何異常的。


問2:
那麼這部分異常怎麼處理呢?
答:見Thread.java 源碼1830行

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

也就是說當run方法內部有異常的時候,JVM會將該沒法捕獲的異常交爲UncaughtExceptionHandler處理,默認UncaughtExceptionHandler爲空null


問3:如何編寫UncaughtExceptionHandler及使用?
前提是繼承Thread類。

public class UncaughtExceptionHandlerImpl implements UncaughtExceptionHandler{


@Override
public void uncaughtException(Thread t, Throwable e) {
//能夠記錄日誌
//能夠釋放資源
//。。。。。。
System.out.println(e); 
}
}


public class TestThread extends Thread{

@Override
public void run() {
int  i = 1/0;
System.out.println(i);
}
public static void main(String[] args) { 

TestThread t = new TestThread();
t.setUncaughtExceptionHandler(new UncaughtExceptionHandlerImpl());
t.start();
}
}

問4:UncaughtExceptionHandler 僅抓exception的異常?
答:不是,這個命名有些迷惑人,實際上你們看源碼就知道uncaughtException(Thread t, Throwable e )
    入參是Throwable接口,因此java.lang.Error和java.lang.Exception都會捕獲。
同時由於工程對其餘中心或是項目引用比較多,常常會有java.lang.NoClassDefFoundError: Could not initialize class 
等相似問題,因此try catch的時候捕獲Throwable比較好


結束語:鑑於上述知識點,建議將全部重要子線程設置UncaughtExceptionHandler,在主線程獲取子線程日誌,不然有問題子線程內部未捕獲,有問題將會石沉大海,沒法定位。
this

相關文章
相關標籤/搜索