Java異常處理機制:try-catch
try{
代碼片段
}catch(XXXException e){
處理try代碼片段中出現的xxxException
}catch(Exception e){
...
}
通常在最后一個catch中捕獲Exception,防止中斷
try的()中只能定義實現了Autocloseable接口的內容。否則會出現編譯不通過的情況,最終編譯器會將代碼改為在finally中關閉這里定義的需要關閉的內容。
何時使用throw拋出一個異常
1.通常遇到以下兩種情況時我們會拋出異常
1.1 當程序遇到一個滿足語法但是不滿足業務邏輯的運行情況時,可以主動實例化一個異常拋出給調用這個以告知這種情況不允許;
1.2 程序確實出現了一個異常,但是該異常不應當在當前代碼段中被解決,可以對外繼續拋出異常
當一個方法中使用throw拋出某個異常時,就要使用throws關鍵字在聲明方法的同時聲明該異常的拋出,以通知調這處理異常只有RuntimeException。在方法中泡壺時可以不在方法上聲明該異常的拋出,除此之外的其他異常則是必須的,否則編譯不通過。
當我們調用一個含有throws聲明異常拋出的方法時就必須處理該異常,否則編譯不通過。處理手段有兩種:
1. 使用try-catch處理該異常
2. 在當前方法上繼續對外拋出取決與業務需求的責任問題,視具體情況而定,不應當在main方法上使用throws聲明異常的拋出。
子類在重寫父類含有throws聲明異常拋出的方法時對於throws的重寫准則。
1. 允許拋出部分異常
2. 允許不再拋出任何異常
3. 允許拋出父類方法拋出異常的子類型異常
4. 不允許拋出其他異常
5. 不允許拋出父類方法拋出異常的父類型異常
RuntimeExcepotion
非檢測異常,因為普通JVM操作引起的運行時異常隨時可能發生,此類異常一般是由特定操作引發,但這些操作在java應用程序中會頻繁出現。因此它們不受編譯器檢查與處理或聲明規則的限制。
常見RuntimeException
IllegalArgumentException 傳遞不合法或者不正確的參數
NullPointerExcepiton 空引用
ArrayIndexOutOfBoundsException 使用的數組下標超出數組允許范圍
ClassCastException 強制轉換為不是實例的子類
NumberFormatException 應用程序視圖將字符串轉換成一種數值類型,但不能轉為適當格式時,拋出該異常
Exception常用API
e.printStackTrace();
e.getMessage();
getCause();檢查異常導致的原因
12.12.3把“被檢查的異常”轉換為“不檢查的異常”
在編寫自己使用的簡單程序時,從main()中拋出異常很方便的,但這不是通用的方法。問題的實質是,當在一個普通方法里調用別的方法時,要考慮到“我不知道該這樣處理這個異常,但是也不想把它‘吞’了,或者打印一些無用的信息”。JDK1.4的異常鏈提供了一種新的思路來解決這個問題。可以直接把“被檢查的異常”包裝進RuntimeExcepiton里面,就像這樣:
try{
// ... to do something useful
}catch(IDontKnowWhatTODoWithThisCheckedException e){
throw new RuntimeException(e);
}
如果想把“被檢查的異常”這種功能“屏蔽”掉的話,這看上去像是一個好辦法。不用“吞下”異常,也不必把它放到方法的異常說明里,而異常鏈還能保證你不會丟失任何原始異常的信息。
這種技巧給了你一種選擇,你可以不寫try-catch字句和/或異常說明,直接忽略異常,讓它自己沿着調用線往上“冒泡”。同時,還可以用getCause()捕獲並處理特定的異常。
異常使用指南
應該在下列情況下使用異常
- 在恰當的級別處理問題(在知道該如果處理的情況下才捕獲異常)
- 解決問題並且重新調用產生異常的方法
- 進行少許修補,然后繞過異常發生的地方繼續執行
- 用別的數據進行計算,以代替方法預計會返回的值
- 把當前運行環境下能做的事情盡量做完,然后把相同的異常拋到更高層
- 把當前運行環境下能做的事情盡量做完,然后把不同的異常拋到更高層
- 終止程序
- 進行簡化。(如果你的異常模式使問題變得太復雜,那用起來會非常痛苦也很煩人。)
- 讓類庫和程序安全。(這既是在為調試做短期投資,也是在為程序的健壯性做長期投資。)