Java - 例外處理 -- 何時該用try/catch?何時該用throws?
發現這個問題容易被忽略,卻很重要,也是有些人包括我都有的疑問。
Java例外處理須注意細節部分滿多,這篇只針對錯誤「該拋還是該處理」做個重點說明:
首先,先了解相關名詞定義:
Java例外處理須注意細節部分滿多,這篇只針對錯誤「該拋還是該處理」做個重點說明:
首先,先了解相關名詞定義:
Java的錯誤以物件呈現。java.lang.Throwable類別下,有2個子類別:
1. 代表嚴重系統錯誤的「java.lang.Error」。
2. 代表程式設計本身錯誤的「java.lang.Exception」。
A. Exception或其子物件(但不是RuntimeException或其子物件):稱為「受檢例外」(Checked Exception)。
受檢例外定義:當設計API的人實作某方法時,某些條件成立下會引發錯誤 => 認定呼叫方法的客戶端有能力處理錯誤,要求編譯器提醒客戶端需明確處理錯誤,否則編譯失敗的例外。e.g. IOException
B. RuntimeException或其子物件:稱為「非受檢例外」(Unchecked Exception)。
非受檢例外定義:當設計API的人實作某方法時,當某些條件成立下會引發錯誤 =>認為API客戶端應在呼叫方法前做好檢查才呼叫方法,避免發生錯誤。而編譯器不會強制提醒要處理錯誤。e.g. ArrayIndexOutOfBoundsException
開始說明錯誤「該拋還是該處理」:
- 設計時無充足資訊知道該如何處理,如:不知道會用在「主控台環境」或「Web環境」,那就可選擇寫throws去拋出例外,讓呼叫方法的客戶端處理。
- 如果過程中會拋出「受檢例外」,但目前環境資訊不足以處理例外,沒法用try catch處理時,可由「呼叫方法的客戶端」依當時呼叫的環境資訊去做處理。用throws去宣告該方法,以拋出的「例外類型」或「父型別」。
- 拋受檢例外,代表我們認為呼叫方法的客戶端「有能力」且「應處理」例外,應用throws,至於要throws哪個類型,客戶端可查API得知,不需查看程式。
- 在例外發生時,可用try catch先處理「當時環境可做的例外處理」。而「當時環境無法決定如何處理的部分」,可用throw拋到呼叫方法的客戶端處理。throw可拋「受檢例外」或「非受檢例外」。e.g.try {//TODO} catch (FileNotFoundException ex) {ex.printStackTrace();throw ex;}return “ok”;
- 如認為客戶端呼叫方法的時機不當,而引發錯誤 => 希望客戶端「做好前置條件檢查再呼叫」時,可拋出非受檢例外。
- 非受檢例外的情形,編譯器不會要求需使用try catch或throws,例外應就任其向外傳播 => 不該用try catch,而是應改善程式邏輯(也就是請客戶端debug此錯誤後再呼叫)以避免錯誤發生。
留言
張貼留言