異常
異常能使錯誤處理代碼變得更有條理,只需在一個地方處理錯誤。把“描述做什么事”的代碼和“出了問題怎么辦”的代碼相分離。先在一個地方專注于正在解決的問題,然后在別的地方處理這些代碼中可能發生的錯誤。
異常情形,在當前環境下無法獲得必要的信息來解決問題。
Java將使用 new在堆上創建異常對象。當前的執行路徑被終止,并且從當前環境中彈出異常對象的引用。異常處理機制接管程序,異常處理程序繼續執行程序。
所有標準異常類都有兩個構造器:一個是缺省構造器;另一個是接受字符串作為參數,用來把相關信息放入異常對象的構造器。
創建一個代表錯誤信息的對象,并且將它從當前環境中“拋出”,這樣就把錯誤信息傳播到了“更大”的環境中,稱為“拋出一個異常”。
因為異常返回的“地點”與普通方法調用返回的“地點”完全不同。異常將在一個恰當的異常處理程序中得到解決。
“終止模型”,一旦異常被拋出,程序無法返回到異常發生的地方繼續執行。
自定義異常
class SimpleException extends Exception {},讓編譯器為你產生缺省構造器。對異常來說,最重要的部分就是類型的名稱。System.err打印到控制臺的標準錯誤流。
異常說明使用了附加的關鍵字 throws,后面接一個所有潛在異常類型的列表,可以聲明方法將拋出異常,實際上卻不拋出。
通過捕獲異常類型的基類Exception,捕獲所有類型的異常。
String getMessage( )
String getLocalizedMessage( )
用來獲取詳細信息,或用本地語言表示的詳細信息。
String toString( )
返回對 Throwable的簡單描述,要是有詳細信息的話,也會把它包含在內。
void printStackTrace( )
輸出到標準輸出流,打印Throwable和Throwable的調用棧軌跡。調用棧顯示了“把你帶到異常拋出地點”的方法調用序列。
重新拋出異常
重拋異常會把異常拋給上一級環境中的異常處理程序。同一個 try 塊的后續 catch 子句將被忽略。
Throwable類被用來表示任何可以作為異常被拋出的類。
Throwable對象可分為兩類:Error編譯期和系統錯誤;Exception 是可以被拋出的基本類型。
異常的基本的概念是用名稱代表發生的問題,并且異常的名稱應該可以望文生意。
運行期異常RuntimeException,屬于錯誤將被自動捕獲。只能在代碼中忽略 RuntimeException(及其子類)類型的異常,其它類型異常的處理都是由編譯器強制實施的。
異常被設計用來處理運行期錯誤,這些錯誤往往是由你的代碼控制能力之外的因素導致的。
finally當你要把除內存之外的資源恢復到它們的初始狀態時,就要用到 finally子句。
編譯器會對異常說明做強制要求,但異常說明本身并不屬于方法原型的一部分,方法原型是由方法的名字與參數的類型組成的。因此,你不能根據異常說明的不同來重載方法。
一個出現在基類方法的異常說明中的異常,不一定會出現在派生類方法的異常說明里。
并不要求拋出的異常同處理程序所聲明的異常完全匹配。派生類的對象也可以匹配處理程序中聲明的基類。,catch(Annoyance e)會捕獲 Annoyance以及所有從它派生的異常。
異常處理的一個重要目標就是把錯誤處理的代碼同錯誤發生的地點相分離。
異常使用指南:
1. 在恰當的級別處理問題。(在你知道該如何處理的情況下才捕獲異常)。
2. 解決問題并且重新調用產生異常的方法。
3. 進行少許修補,然后繞過異常發生的地方繼續執行。
4. 用別的數據進行計算,以代替方法返回的期望值。
5. 把當前運行環境下能做的事情盡量作完,然后把相同的異常重拋(rethrow)到
更高層。
6. 把當前運行環境下能做的事情盡量作完,然后把不同的異常拋(throw)到更高
層。
7. 終止程序。
8. 進行簡化。(如果異常把問題搞得太復雜,那用起來會非常痛苦也很煩人。)
9. 讓類庫和程序更安全。(這既是在為調試做短期投資,也是在為程序的健壯性做
長期投資。)