天天看點

java補完——深入了解異常機制(待深入)關于執行順序(前言)異常體系(父類Throwable )根據業務需求建立自己的異常異常處理政策java異常捕獲、抛出實作

文章說明:黑色字型-已知,藍色字型-所見即所得,紅色字型-還需要再找資料弄明白的,黃色背景-提煉關鍵資訊

參考資料:很多參考資料,段落下有原文連結到原作者

關于執行順序(前言)

1、try+catch

2、try+catch+finally

3、try+finally

try有異常執行finally。finally後面的代碼不會執行。因為沒有處理異常,是以遇到異常後,執行完finally後,方法就已抛出異常的方式退出了。

(假設方法需要傳回值)

無異常無finally,直接return。

有 finally,try 裡的 return 不會立即執行,先執行 finally ,若 finally 裡沒有 return 或沒有能夠終止程式的代碼,執行完 finally 之後再執行 return 結束方法。

若 finally 裡有 return 或含有能夠終止程式的代碼,執行完 finally 之後結束,不執行 return。

在抛出異常的情況下原理也是一樣的,把上面說到的 try 換成 catch 去了解就 OK 了,即catch中無論是傳回還是抛出異常,最終傳回的均是finally中的結果,除非finally無傳回。

異常體系(父類Throwable )

java.lang.Throwable 是java中異常的基類,通過Throwable 的內建實作關系可以看出, Error 、Exception 都是繼承與Throwable,是以Throwable是java語言體系中異常的超類(父類)。

(1)檢查性異常

可查異常:Exception 中非運作時異常,不處理編譯不通過,可預見,不做處理,線程中斷。try catch 捕獲 或者 throws 向上抛出。

(2)非檢查性異常(Error、運作時異常 RuntimeException及其之類)

編譯器不要求強制處置

分為Error 及運作時異常及其之類

運作時異常及其之類可以在程式中捕獲也可以不做捕獲,編譯都可以通過,盡可能的注意程式邏輯避免運作時異常(NullPointerException、IndexOutOfBoundsException)

如果運作過程中發生非檢查性異常,處理的辦法是找到發生異常的錯誤代碼或者伺服器硬體資源問題處理掉,而不是捕獲,這實際上是java多異常做的擴充、容錯

(3)Error

  1. Error是程式無法處理的錯誤,是以Error異常是不需要捕獲的

    2)Error異常是不應該發生的異常情況,是以在程式編譯時是不被檢查的(非檢查性異常)

    3)程式一旦發生Error異常,線程停止,web項目通常會報500頁面(OutOfMemoryError、ThreadDeath、NoClassDefFoundError)

    4)一個設計合理的程式是不應該出現Erro錯誤的,一旦出現也不需要用程式補救的方式來處理Error異常

    (4)Exception

  2. 程式本身可以處理

    2)分為運作時異常和非運作時異常,運作時異常為非檢查性異常,非運作時異常為檢查性異常

    3)當程式中出現非運作時異常時(Exception中除RuntimeException及其之類之外),要不捕獲、要麼向上抛出throws,否則線程中斷

根據業務需求建立自己的異常

(1)java自帶異常不能夠說明系統發生異常的具體情況

(2)根據業務場景設定可讀性強、易于了解、友善系統業務流轉的異常(如前後端多場景互動等)

(3)一般通過異常類的名稱或内部提示語進行設計,指明用意,便于了解

異常處理政策

(1)如果确定該方法中會發生那些異常并知道如何處理,處理後的業務流程走向也明确,則進行異常捕獲并處理

(2)如果不确定該方法中會發生那些異常,或不知道怎麼處理這些異常,則向上抛出,又最後一層異常攔截器進行管理

java異常捕獲、抛出實作

1、try、catch 、 finally

可以有多個catch。

2、代碼實作區如果有異常抛出,則該方法立即建立異常對象(異常的類型已經确定了),并将該異常抛出監控區域外,尋找比對類型相容的catch子句,若比對成功(父類及其本身都可比對),則執行該catch子句的實作,異常捕獲處理結束,如果有finally定義則繼續執行finally代碼塊。

3、隻要有一個catch子句比對成功,則整個捕獲過程結束,是以在實作多級catch子句處理時要注意T1、T2、T3…異常類型的歸屬關系,例如父子關系的異常類型 : Exception是CloneNotSupportedException的父類,而CloneNotSupportedException 是 ServerCloneException 的父類, 根據隻要catch比對整個捕獲就結束這個原理,可以得出如果把ServerCloneException 放到第三級catch,把CloneNotSupportedException 放在第二級catch,Exception放在第一級catch,即:

try {

//異常監控區或叫作代碼實作區

// 程式業務實作代碼

} catch (Exception t1){

// 捕獲異常類型為T1的異常

} catch (CloneNotSupportedException t2){

//捕獲異常類型為T2的異常

} catch (ServerCloneException t3){

//捕獲異常類型為T3的異常

} finally{

//最後處理實作,不管異常是否捕獲都會執行的代碼

}

後兩級catch子句永遠都不會被執行,因為第一級永遠會優先于後兩級比對,是以要按異常類型級别從低到高的順序排放catch子句,即ServerCloneException 、CloneNotSupportedException 、Exception

4、finally塊也不是肯定會執行的,以下情況不會執行:

finally裡發生異常時,finally執行中斷

在try或者catch裡執行了System.exit(),finally也不會再執行了

由于伺服器硬體資源引起的線程死亡也會導緻finally不能執行

5、抛出異常 throws throw

(1)throws

java代碼抛出異常使用throw (任何java代碼都可以抛出)

方法抛出異常使用throws ,且可以同時抛出多個異常

異常可以不斷向上抛出,直到最後一層調用方法,即最後一層調用方法必須處理,否則發生錯誤

方法覆寫,覆寫方法抛出的異常類型必須是被覆寫方法所聲明異常的同類或子類,例如接口聲明方法是IndexOutOfBoundsException,而實作類彙總覆寫方法抛出的異常類型為Exception,此時程式編譯報錯

(2)throw

在java代碼中以throw 抛出Throwable類型的異常執行個體對象

throw 一旦執行,該方法體立即停止運作(throw後面的代碼不會再執行了)

throw 抛出異常類型後,本方法的catch子句或上層各級調用方法的catch子句開始比對該異常類型,直到比對成功後,開始執行catch子句代碼實作,如果沒有比對到合适的catch子句,最後交由JVM處理,列印異常資訊且導緻該線程停止工作

原文連結:https://blog.csdn.net/suoyanming/article/details/89191135

原文連結:https://blog.csdn.net/hejingyuan6/article/details/51296904