Java 異常處理相關

相關類的結構以下所示

  • java.lang.Objectjava

    • java.lang.Throwable數組

      • java.lang.Error
      • java.lang.Exception函數

        • java.lang.RuntimeException

Throwable類

  • Throwable 類是Java語言中全部錯誤和異常的超類,只有當一個對象直接或者間接的是此類的實例時,Java才能經過throw語句拋出異常,一樣,只有這種類才能被try……catch語句捕獲進行處理
  • Throwable類的子類Error是錯誤,不是程序能夠處理的,通常會是內存不足,線程終止,Java虛擬機運行錯誤等,只能聽之任之,JVM一般會kill掉這個進程
  • Throwable類的子類Exception是異常,是程序能夠處理的,進一步分爲CheckedException 和 UncheckedException性能

    • CheckedException發生在編譯階段,代碼語句必須使用try……catch或者throws,不然沒法進行編譯,好比StreamTokenizer必須聲明拋出異常IOException,除了Runtime Exception類集以外,其餘的Exception類集都是CheckeException
    • UncheckedException發生在程序的運行階段,通常來講具備不肯定性,不容易定位和DEBUG

Exception類

  • 該類指出了合理的應用程序想要捕獲的異常條件,有兩個參數,默認構造能夠是兩個可選參數,一個是詳細信息,一個是異常緣由,分別對應下述四個構造方法,分別於super對應線程

    • public Exception()
    • public Exception(String message)
    • public Exception(String message, Throwable cause)
    • public Exception(Throwable cause)

RuntimeException類

  • RuntimeException是那些在Java 虛擬機正常運行期間拋出的異常的超類,屬於uncheckedException,好比說發生數組越界,空指針等邏輯引發的問題
  • 可能在執行方法期間拋出,可是沒有被捕獲的RuntimeException的任何子類都不用在throws子句中聲明
  • 包含四個構造方法指針

    • RuntimeException()
    • RuntimeException(String message)
    • RuntimeException(String message, Throwable cause)
    • RuntimeException(Throwable cause)

try - catch - finally

  • 在try代碼片斷中,包含着有可能拋出異常的語句,若是無異常,則直接跳到finally代碼塊,不然相應的捕獲異常,執行catch代碼塊的內容
  • 不管是否try代碼塊發生異常,finally都會被執行,能夠在這裏進行一些接口的close操做等
  • 若是代碼中顯式的聲明瞭某一個異常類型,則異常處理機制不會顯示這個異常是在哪裏拋出的,若是是沒有聲明異常遭遇中斷,異常處理會顯示出處
  • 每個catch按照書寫的前後依次匹配執行,一旦亦常被某一個catch捕獲,則必不會被其餘的catch捕獲處理
  • 當try代碼塊或者catch代碼塊中包括return語句的時候,finally代碼塊將會在return以前被強制執行,finally不被執行僅僅當下列條件被知足:對象

    • 代碼在finally代碼塊以前即發生錯誤
    • 代碼在finally代碼塊以前進行了System.exit()
    • 當前線程因爲某種狀況丟失
    • 關機,或者各類奇葩的可能條件

throw 和 throws

  • throws 是方法拋出異常的聲明,表示一個預動做,說明下方方法可能會拋出異常,throws不作其餘處理,僅僅是上交異常到調用,方法中拋出的任何異常都必須有throws聲明,除非是將交由運行時系統自動拋出的RuntimeException
  • throw是拋出異常,是一個明確的動做,必須與try……catch或者throws一塊兒使用,拋出的只能是Throwable的類集中的類,若是全部的方法都將異常往上層調用者拋,那麼JVM最後的處理就是打印異常消息和堆棧信息

自定義異常類型

通常來講,套路以下:繼承

  1. 定義一個類,繼承自Throwable或者某一個子類
  2. 構造方法,或者直接使用super的構造方法
  3. throws聲明,在代碼塊的某處throw該異常類
  4. catch到拋出的異常進行處理

異常鏈機制

  • 當異常較少的時候,咱們能夠對每個異常進行try 和catch, 可是若是出現多個異常,顯然經過一個Exception處理全部異常的方式會增長維護代碼DEBUG的困難度,因此咱們須要將異常信息進行封裝,而後捕獲咱們的異常封裝類便可
  • 異常的處理方式有兩種,一種是throws拋出異常後交給上級去處理,另外一種就是使用try和catch進行具體的修正處理,異常鏈的處理採用第一種方式,在try ……catch的catch代碼塊中不作任何處理,惟一的動做就是拋出封裝好的異常信息,而後會有throws拋出該異常,遞歸的每一層都如此控制異常拋出,就造成了一條異常鏈
  • 若是咱們想要在捕獲到一個異常後拋出另一個異常,那麼,咱們能夠調用Throwable類集的getCause()方法,獲得類中的cause參數,這個參數保存的就是原始存有的異常信息,也就是說cause是致使拋出該throwable的throwable
  • 保留有異常鏈的catch代碼塊中可使用Throwable的printStackTrace()方法來打印整個異常信息
  • getCause() 返回由一個須要Throwable的構造方法提供的cause,或者是在建立Throwable以後經過initCause()來設定cause,子類沒必要要重寫,也沒必要重寫printStackTrace()
  • printStackTrace()方法會將對象的堆棧跟蹤輸出到輸出流,做爲System.err的值

幾個建議

  • 儘可能在try中不要包含太多的代碼,縮小異常範圍圈
  • 若是有的接口即便有異常也照樣要運行,那麼應該使用finally
  • 縮小catch捕獲的異常,儘可能使catch捕獲明確的單個異常
  • 拋出異常的時候,儘可能包含易讀易懂的描述和名稱
  • 不在構造函數中拋出異常,不在finally代碼塊中處理返回
  • 不要老拋出異常,會下降Java的效率和系統的性能
相關文章
相關標籤/搜索