1. 程式人生 > >error和exception的區別,RuntimeException和非RuntimeException的區別

error和exception的區別,RuntimeException和非RuntimeException的區別

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

1. 異常機制
      異常機制是指當程式出現錯誤後,程式如何處理。具體來說,異常機制提供了程式退出的安全通道。當出現錯誤後,程式執行的流程發生改變,程式的控制權轉移到異常處理器。

      傳統的處理異常的辦法是,函式返回一個特殊的結果來表示出現異常(通常這個特殊結果是大家約定俗稱的),呼叫該函式的程式負責檢查並分析函式返回的結果。這樣做有如下的弊端:例如函式返回-1代表出現異常,但是如果函式確實要返回-1這個正確的值時就會出現混淆;可讀性降低,將程式程式碼與處理異常的程式碼混爹在一起;由呼叫函式的程式來分析錯誤,這就要求客戶程式設計師對庫函式有很深的瞭解。
異常處理的流程:
① 遇到錯誤,方法立即結束,並不返回一個值;同時,丟擲一個異常物件 。
② 呼叫該方法的程式也不會繼續執行下去,而是搜尋一個可以處理該異常的異常處理器,並執行其中的程式碼 。

2 異常的分類
異常的分類:
① 異常的繼承結構:基類為Throwable,Error和Exception繼承Throwable,RuntimeException和IOException等繼承Exception,具體的RuntimeException繼承RuntimeException。
② Error和RuntimeException及其子類成為未檢查異常(unchecked),其它異常成為已檢查異常(checked)。

每個型別的異常的特點
Error體系 :
      Error類體系描述了Java執行系統中的內部錯誤以及資源耗盡的情形。應用程式不應該丟擲這種型別的物件(一般是由虛擬機器丟擲)。如果出現這種錯誤,除了盡力使程式安全退出外,在其他方面是無能為力的。所以,在進行程式設計時,應該更關注Exception體系。

Exception體系包括RuntimeException體系和其他非RuntimeException的體系 :
① RuntimeException:RuntimeException體系包括錯誤的型別轉換、陣列越界訪問和試圖訪問空指標等等。處理RuntimeException的原則是:如果出現RuntimeException,那麼一定是程式設計師的錯誤。例如,可以通過檢查陣列下標和陣列邊界來避免陣列越界訪問異常。
②其他非RuntimeException(IOException等等):這類異常一般是外部錯誤,例如試圖從檔案尾後讀取資料等,這並不是程式本身的錯誤,而是在應用環境中出現的外部錯誤。

與C++異常分類的不同 :
① Java中RuntimeException這個類名起的並不恰當,因為任何異常都是執行時出現的。(在編譯時出現的錯誤並不是異常,換句話說,異常就是為了解決程式執行時出現的的錯誤)。
② C++中logic_error與Java中的RuntimeException是等價的,而runtime_error與Java中非RuntimeException型別的異常是等價的。
3 異常的使用方法
宣告方法丟擲異常
① 語法:throws(略)
② 為什麼要宣告方法丟擲異常?
      方法是否丟擲異常與方法返回值的型別一樣重要。假設方法丟擲異常卻沒有宣告該方法將丟擲異常,那麼客戶程式設計師可以呼叫這個方法而且不用編寫處理異常的程式碼。那麼,一旦出現異常,那麼這個異常就沒有合適的異常控制器來解決。
③ 為什麼丟擲的異常一定是已檢查異常?
      RuntimeException與Error可以在任何程式碼中產生,它們不需要由程式設計師顯示的丟擲,一旦出現錯誤,那麼相應的異常會被自動丟擲。而已檢查異常是由程式設計師丟擲的,這分為兩種情況:客戶程式設計師呼叫會丟擲異常的庫函式(庫函式的異常由庫程式設計師丟擲);客戶程式設計師自己使用throw語句丟擲異常。遇到Error,程式設計師一般是無能為力的;遇到RuntimeException,那麼一定是程式存在邏輯錯誤,要對程式進行修改(相當於除錯的一種方法);只有已檢查異常才是程式設計師所關心的,程式應該且僅應該丟擲或處理已檢查異常。
      注意:覆蓋父類某方法的子類方法不能丟擲比父類方法更多的異常,所以,有時設計父類的方法時會宣告丟擲異常,但實際的實現方法的程式碼卻並不丟擲異常,這樣做的目的就是為了方便子類方法覆蓋父類方法時可以丟擲異常。

如何丟擲異常
① 語法:throw(略)
② 丟擲什麼異常?對於一個異常物件,真正有用的資訊時異常的物件型別,而異常物件本身毫無意義。比如一個異常物件的型別是ClassCastException,那麼這個類名就是唯一有用的資訊。所以,在選擇丟擲什麼異常時,最關鍵的就是選擇異常的類名能夠明確說明異常情況的類。
③ 異常物件通常有兩種建構函式:一種是無引數的建構函式;另一種是帶一個字串的建構函式,這個字串將作為這個異常物件除了型別名以外的額外說明。
④ 建立自己的異常:當Java內建的異常都不能明確的說明異常情況的時候,需要建立自己的異常。需要注意的是,唯一有用的就是型別名這個資訊,所以不要在異常類的設計上花費精力。

捕獲異常
      如果一個異常沒有被處理,那麼,對於一個非圖形介面的程式而言,該程式會被中止並輸出異常資訊;對於一個圖形介面程式,也會輸出異常的資訊,但是程式並不中止,而是返回用錯誤頁面。
      語法:try、catch和finally(略),控制器模組必須緊接在try塊後面。若擲出一個異常,異常控制機制會搜尋引數與異常型別相符的第一個控制器隨後它會進入那個catch 從句,並認為異常已得到控制。一旦catch 從句結束對控制器的搜尋也會停止。
      捕獲多個異常(注意語法與捕獲的順序)(略)
      finally的用法與異常處理流程(略)
      異常處理做什麼?對於Java來說,由於有了垃圾收集,所以異常處理並不需要回收記憶體。但是依然有一些資源需要程式設計師來收集,比如檔案、網路連線和圖片等資源。
      應該宣告方法丟擲異常還是在方法中捕獲異常?原則:捕捉並處理哪些知道如何處理的異常,而傳遞哪些不知道如何處理的異常。
再次丟擲異常
①為什麼要再次丟擲異常? 在本級中,只能處理一部分內容,有些處理需要在更高一級的環境中完成,所以應該再次丟擲異常。這樣可以使每級的異常處理器處理它能夠處理的異常。
②異常處理流程 :對應與同一try塊的catch塊將被忽略,丟擲的異常將進入更高的一級。
4 關於異常的其他問題
① 過度使用異常 :首先,使用異常很方便,所以程式設計師一般不再願意編寫處理錯誤的程式碼,而僅僅是簡簡單單的丟擲一個異常。這樣做是不對的,對於完全已知的錯誤,應該編寫處理這種錯誤的程式碼,增加程式的魯棒性。另外,異常機制的效率很差。
② 將異常與普通錯誤區分開:對於普通的完全一致的錯誤,應該編寫處理這種錯誤的程式碼,增加程式的魯棒性。只有外部的不能確定和預知的執行時錯誤才需要使用異常。
③ 異常物件中包含的資訊 :一般情況下,異常物件唯一有用的資訊就是型別資訊。但使用異常帶字串的建構函式時,這個字串還可以作為額外的資訊。呼叫異常物件的getMessage()、toString()或者printStackTrace()方法可以分別得到異常物件的額外資訊、類名和呼叫堆疊的資訊。並且後一種包含的資訊是前一種的超集。

 

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述