八 Java异常
文章目錄
- 什么是異常
- 異常分類
- 異常體系結構
- Error
- Exception
- 異常處理機制
- 自定義異常
- 實際應用中的總結
什么是異常
- 實際工作中,遇到的情況不可能是非常完美的。比如:你寫的某個模塊,用戶輸入不一定符合你的要求、你的程序要打開某個文件,這個文件可能不存在或者文件格式不對,你要讀取數據庫的數據,數據可能是空的等。我們的程序再跑著,內存或硬盤可能滿了,等等。
- 軟件程序在運行過程中,非常可能遇到剛剛提到的這些異常問題,我們叫異常,英文是:Exception,意思是例外。這些,例外情況,或者叫異常,怎么讓我們寫的程序做出合理的處理。而不至于程序崩潰。
- 異常指程序運行中出現的不期而至的各種狀況,如:文件找不到、網絡連接失敗、非法參數等。
- 異常發生在程序運行期間,它影響了正常的程序執行流程。
異常分類
- 檢查性異常:最具代表的檢查性異常是用戶錯誤或問題引起的異常,這是程序員無法預見的。例如要打開一個不存在文件時,一個異常就發生了,這些異常在編譯時不能被簡單地忽略。
- 運行時異常:運行時異常是可能被程序員避免的異常。與檢查性異常相反,運行時異常可以在編譯時被忽略。
- 錯誤ERROR:錯誤不是異常,而是脫離程序員控制的問題。錯誤在代碼中通常被忽略。例如,當棧溢出時,一個錯誤就發生了,它們在編譯也檢查不到的。
異常體系結構
-
Java把異常當作對象來處理,并定義一個基類java.lang.Throwable作為所有異常的超類。
-
在Java API中已經定義了許多異常類,這些異常類分為兩大類,錯誤Error和異常Exception。
Error
- Error類對象由Java 虛擬機生成并拋出,大多數錯誤與代碼編寫者所執行的操作無關。
- Java虛擬機運行錯誤(Virtual MachineError),當JVM不再有繼續執行操作所需的內存資源時,將出現 OutOfMemoryError。這些異常發生時,Java虛擬機(JVM)一般會選擇線程終止;
- 還有發生在虛擬機試圖執行應用時,如類定義錯誤(NoClassDefFoundError)、鏈接錯誤(LinkageError)。這些錯誤是不可查的,因為它們在應用程序的控制和處理能力之外,而且絕大多數是程序運行時不允許出現的狀況。
Exception
- 在Exception分支中有一個重要的子類RuntimeException(運行時異常)
- ArrayIndexOutOfBoundsException(數組下標越界)
- NullPointerException(空指針異常)
- ArithmeticException(算術異常)
- MissingResourceException(丟失資源)
- ClassNotFoundException(找不到類)等異常,這些異常是不檢查異常,程序中可以選擇捕獲處理,也可以不處理。
- 這些異常一般是由程序邏輯錯誤引起的,程序應該從邏輯角度盡可能避免這類異常的發生;
Error和Exception的區別
? Error通常是災難性的致命的錯誤,是程序無法控制和處理的,當出現這些異常時,Java虛擬機(JVM)一般會選擇終止線程;Exception通常情況下是可以被程序處理的,并且在程序中應該盡可能的去處理這些異常。
異常處理機制
- 拋出異常
- 捕獲異常
- 關鍵字:try、catch、finally、throw、throws
代碼示例
public class Test {public static void main(String[] args) {int a = 1;int b = 0;//假設要捕獲多個異常:從小到大//Ctrl+Alt+T 快捷鍵try{//try監控區new Test().test(a,b);}catch (Error e){//catch(想要捕獲的異常類型) 捕獲異常System.out.println("程序出現異常,變量b不能為0");}catch (Exception e){//catch(想要捕獲的異常類型) 捕獲異常System.out.println("程序出現異常,變量b不能為0");e.printStackTrace();//打印錯誤的棧信息}catch (Throwable e){//catch(想要捕獲的異常類型) 捕獲異常System.out.println("程序出現異常,變量b不能為0");}finally {//finally 處理善后工作(例如關閉io流,資源) ,finally可以沒有System.out.println("finally");}}//假設這個方法中,處理不了這個異常,方法上拋出異常 throwspublic void test(int a,int b)throws ArithmeticException{if(b==0){throw new ArithmeticException();//主動拋出異常,一般在方法中使用 throw}} }運行結果
注意打印的異常信息在最后面
自定義異常
- 使用Java內置的異常類可以描述在編程時出現的大部分異常情況。除此之外,用戶還可以首定義異常。用戶自定義異常類,只需繼承Exception類即可。
- 在程序中使用自定義異常類,大體可分為以下幾個步驟:
- 創建自定義異常類。
- 在方法中通過throw關鍵字拋出異常對象。
- 如果在當前拋出異常的方法中處理異常,可以使用try-catch語句捕獲并處理;否則在方法的聲明處通過throws關鍵字指明要拋出給方法調用者的異常,繼續進行下一步操作。
- 在出現異常方法的調用者中捕獲并處理異常。
代碼示例
//自定義異常 public class MyException extends Exception{//傳遞數字 > 10private int detail;public MyException(int a){this.detail = a;}//toString : 異常的打印信息@Overridepublic String toString() {return "MyException{" +"detail=" + detail +'}';} } //測試類 public class Test {//可能會存在異常的方法static void test(int a) throws MyException {System.out.println("傳遞的參數為"+a);if(a>10){throw new MyException(a);}System.out.println("OK");}public static void main(String[] args) {try {test(11);} catch (MyException e) {System.out.println("Exception=>"+e);}} }執行結果
實際應用中的總結
- 處理運行時異常時,采用邏輯去合理規避同時輔助try-catch處理
- 在多重catch塊后面,可以加一個catch (Exception)來處理可能會被遺漏的異常
- 對于不確定的代碼,也可以加上try-catch,處理潛在的異常
- 盡量去處理異常,切忌只是簡單地調用printStackTrace()去打印輸出
- 具體如何處理異常,要根據不同的業務需求和異常類型去決定
tch塊后面,可以加一個catch (Exception)來處理可能會被遺漏的異常 - 對于不確定的代碼,也可以加上try-catch,處理潛在的異常
- 盡量去處理異常,切忌只是簡單地調用printStackTrace()去打印輸出
- 具體如何處理異常,要根據不同的業務需求和異常類型去決定
- 盡量添加finally語句塊去釋放占用的資源
總結