【Java語言基礎】異常處理機制

異常處理的基礎知識

即使是有經驗的程序員,也難免出現編程錯誤。

編程錯誤分類

  1. 編譯錯誤(compilation error)
    1. 原因:沒有遵循語言的規則
    2. 解決方法:由編譯程序檢查發現
  2. 邏輯錯誤(logic error)
    1. 原因:程序沒有按照預期的方案執行
    2. 解決方法:利用調試技巧可以解決此類錯誤
  3. 運行時錯誤(runtime error)
    1. 原因:在程序運行過程中,出現了不可能執行的操作
    2. 解決方法:異常處理

運行時錯誤(runtime error)

在程序運行時出現一些非正常的現象被稱爲運行時錯誤,如除數爲0,數組下標越界,文件不存在,內存不夠用等等0

分類:根據錯誤性質將運行時錯誤分爲兩類

  • 致命性的錯誤
    例:程序進入了死循環,遞歸無法結束,內存溢出等,這些運行錯誤是致命性的錯誤,只能在編程階段解決,運行時程序本身無法解決,只能依靠其他程序干預,否則會一直處於非正常狀態。
    錯誤處理一般由系統承擔,語言本身不提供錯誤處理機制。
  • 非致命性的異常
    例:除數爲0,操作數超出數據範圍,文件並不存在,欲裝入的類文件丟失,網絡連接中斷等,這類現象稱爲非致命性的異常。
    是可以檢測和處理的,所以產生了相應的異常處理機制。

異常處理的類層次

Java中預定義了很多異常類,每個異常類代表一種運行錯誤

  • Error:災難性故障,由Java虛擬機生成並拋出給系統。通常,Java程序不對錯誤進行處理。
  • Exception:是用戶程序能夠捕捉到的“異常”情況,由Java程序拋出和處理。
常用的Exception類的子類:
異常類 描述
NullPointerException 空指針異常
ArrayIndexOutOfBoundsException 數組越界訪問異常
ClassNotFoundException 試圖訪問一個根本不存在的類
IOException 輸入/輸出異常
NumberFormatException 錯誤的類型轉換異常
ArrayStoreException 當向數組存入錯誤類型數據時
ArithmeticException 除數爲0的算數異常

未被捕獲“異常”

“異常”對象是Java運行時堆某些“異常”情況作出反應而產生的。如果不處理“異常”會有什麼樣的情況發生?

public class _519test {
    public static void main(String[] args) {
    	//當執行到該語句時,系統檢測到被0除,構造一個“異常”對象來發異
        int a = 4 / 0;
    }
}

程序沒有提供任何處理異常的異常處理程序,所以該異常被Java運行時系統的默認處理程序捕獲,顯示一個描述異常的字符串,打印異常發生出的堆棧軌跡並且終止程序。

異常處理機制

Java提供了異常處理機制,通過面向對象的方法來處理異常。

  • 在程序運行的過程中,如果發生了異常,則該程序(或虛擬機)生成一個代表該異常類的對象(包含該異常的詳細信息),並把交給運行時系統;
  • 運行時系統從生成對象的代碼開始,沿方法的調用棧逐層回溯查找,直到找到包含相對應處理代碼的方法,並把異常對象交給該方法,來處理這一異常。

異常捕獲

  1. 發現異常的代碼“拋出”異常
  2. 運行時系統“捕獲”異常
  3. 由程序員編寫的相應代碼“處理”異常

使用方法

使用try-catch-finally語句捕獲和處理異常
格式

try{
	//可能產生異常的語句
}
catch(異常類 變量){
	//異常處理代碼
}
[finally{
	//必須執行的代碼,可有可無
}]

try語句塊

  • 將程序只能可能出現異常的代碼放入try塊中。
  • 當try塊中有語句引發異常時,系統將不再執行try塊中未執行的語句,而執行匹配的catch塊。
  • 如果try塊中沒有語句引發異常,則程序執行完try塊中的語句後不執行catch塊中的,即跳過catch語句,繼續執行後面的程序。

catch塊

  • 每個try語句後面必須伴隨一個或多個catch語句,用於捕捉try語句塊所產生的異常並作相應的處理。
  • catch自居的目標是解決“異常”情況,並像沒有出錯一樣繼續運行。
    例如:
try{
	int a = 4 / 0;
}catch(ArithmeticException e){
	System.out.println(e.toString());
}

注意:
一個try和它的catch語句組成了一個單元。catch字句的範圍限制於try語句塊中的語句。一個catch語句不能捕獲另一個try聲明所引發的異常(除非是嵌套的try語句情況)。被try保護的語句聲明必須在一個大括號內,try語句塊不能單獨使用。

多個catch塊

一個catch塊只能處理一類異常,當try塊中的與劇組可能拋出多種異常時,就需要有多個catch來分別處理各種異常。

  • 一個異常對象能否被一個catch塊接收主要看該異常對象與catch塊中聲明的異常類的匹配情況,當它們滿足下面條件中的任一條時,異常對象將被接收:
    • 異常對象是catch塊中聲明的異常類的實例;
    • 異常對象是catch塊中聲明的異常類的子類的實例;
    • 異常對象實現了catch塊中聲明的異常類的接口。
  • 當使用多個catch塊時,需要注意catch子句排列順序**–先特殊到一般,**也就是子類在父類前面。如果子類在父類後面,子類將永遠不會到達。

try語句的嵌套

一個try語句可以在另一個try塊內部----try語句的嵌套

  • 每次進入try語句,異常的前後關係都會被壓入堆棧。如果一個內部的try語句不含特殊異常的catch處理程序,堆棧將彈出,下一個try語句的catch處理程序將檢查是否與之匹配。
  • 這個過程將繼續直到一個catch語句匹配後,或者是直到所有的嵌套try語句被檢查耗盡。
  • 如果沒有catch語句匹配,Java的運行時系統將處理這個異常。

未完…


筆記源於上課老師的PPT

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