黑馬程序員——異常處理

------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a>、期待與您交流! ----------

在程序運行過程中,可能發生異常,也就是出現錯誤。出現錯誤的原因可能是由程序本身編寫上的邏輯錯誤引起的,也有可能是在應用環境下,出現的外部錯誤。出現異常後,需要處理,java將程序中的異常包裝成異常類——Exception。Exception繼承自Throwable,同樣繼承自Throwable的類還有Error,但Error不希望被程序捕獲處理,需由虛擬機自己處理,並使程序停止運行;Exception可以被程序捕獲(catch)並處理。

異常拋出,可以是在程序運行時發生並由虛擬機拋出,也可以是由throw語句拋出。其中非RuntimeException只能由throw語句拋出,且必需在其方法名上標註throws語句(throws X_Exception),throws語句拋出的異常必須是方法中throw語句拋出異常的父類或同類。RuntimeException由throw語句拋出時,可以不在方法名上標註throws語句。由throws語句拋出非RuntimeException的方法在調用時必須處理異常或繼續向上拋出異常。

對代碼進行異常檢查處理的格式爲:

try{
      代碼塊
}
catch(X_Exception  xe){
      異常處理代碼
}
finally{
      必須執行的代碼
}
異常發生後,經過此格式的處理後將繼續執行try—finally下面的代碼,如果未做此處理(RuntimeException不會強制檢查,運行時檢查)或向上拋出了異常,則方法會直接返回,下面的代碼不會再被執行。在try代碼塊內部,發生異常位置後的代碼仍不得執行。

異常處理的一種設計模型是把try塊和catch處理代碼放入while循環中,捕獲異常後做異常處理再重新調用try塊中的內容,直到不再發生異常。但更多的設計是不再做這種恢復,因爲這增加了代碼編寫和維護的困難,對於大型程序更是如此,因爲異常可能會從許多地方拋出。

關於繼承:
子類重寫父類的帶有throws語句(即會拋出異常的方法)的方法時,也必須拋出父類該方法拋出異常的同類或子類。

關於重新拋出異常:
通過try檢查異常並通過catch捕獲異常後,可以再次拋出該異常,此時拋出的異常帶有原來的棧軌跡,如果調用異常的fillInStackTrace()方法(該方法返回Throwable對象),就會產生一個帶有原來異常信息卻帶有新的拋出點棧軌跡的異常對象。另外,可以將非RuntimeException包裝成RuntimeException上拋,方法如下:

try{
.../
}
catch(AException ae){
...
throw new RuntimeException(ae);
}

異常鏈:
捕獲一個異常後,拋出另一個異常,同時希望把原來的異常保存下來,這被成爲異常鏈。構造異常鏈,是通過把原來的異常對象傳入新異常的構造方法產生新異常對象的方式構造的。Error、Exception和RuntimeException都有這樣的構造方法,傳入的都是Throwable對象。除了用構造函數的方法還可以調用新創建的異常的initCause(Throwable t)方法(Throwable的方法)將原來的異常初始化爲新異常的cause。

finally子句:
finally後面花括號內的代碼,是一定被執行的部分,無論是否發生異常,都會被執行,即使在try—finally中間有return語句,finally子句中的內容也會被執行。當要把除內存之外的資源恢復到它們的初始狀態時,就要用到finally子句。這種需要清理的資源包括:已經打開的文件或網絡連接,在屏幕上的圖形,甚至可以是外部世界的某個開關。如果把這些動作放在catch子句中,可能會因爲異常未被捕獲而不得執行。
如果把finally子句和帶標籤的break和continue配合使用,在Java中就沒必要使用goto語句了。
在try—finally語句中,如果繼續向外拋出了異常1,而同時在finally子句中由拋出了異常2,未經處理的異常1會被異常2代替,外部只能捕獲異常2。
在finally子句中如果有return語句,拋出異常的方法正常返回,如果仍向外部拋出了異常,此異常視爲未發生,也不會被外部相應的catch捕獲到。

關於方法重寫時,異常的拋出聲明:
子類重寫父類方法時,拋出的異常必須是父類聲明的異常的同類或子類或者不拋出異常;子類繼承一個父類同時實現一個接口,接口和父類具有同一個方法時,父類拋出的異常是接口拋出異常的同類或子類或者不拋出異常。對於構造方法不用受此限制。

異常使用指南:
應該在以下情況下使用異常:
1)在恰當的級別處理問題。(在知道該如何處理的情況下捕獲異常。)
2)解決問題並且重新調用產生異常的方法。
3)進行少許修補,然後繞過異常發生的地方繼續執行。
4)用別的數據進行計算,以代替方法預計會返回的值。
5)把當前運行環境下能做的事情儘量做完,然後把相同的異常重新拋到更高層。
6)把當前運行環境下能做的事情儘量做完,然後把不同的異常拋到更高層。
7)終止程序。
8)進行簡化。
9)讓類庫和程序更安全。(這既是在爲調試做短期投資,也是在爲程序的健壯性做長期投資)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章