Java異常捕獲與處理

Java異常捕獲與處理

1 異常(Exception)

  異常是程序中的一些錯誤,但並不是所有的錯誤都是異常,並且錯誤有時候是可以避免的。異常發生的原因有很多,例如:用戶輸入了非法數據、要打開的文件不存在、網絡通信時連接中斷或者JVM內存溢出等。菜鳥教程

2 異常分類

  • 檢查性異常:最具代表的檢查性異常是用戶錯誤或問題引起的異常,這是程序員無法預見的。
  • 運行時異常:運行時異常是可能被程序員避免的異常。與檢查性異常相反,運行時異常可以在編譯時被忽略。
  • 錯誤ERROR:錯誤不是異常,而是脫離程序員控制的問題。錯誤在代碼中通常被忽略。例如,當棧溢出時,一個錯誤就發生了,它們在編譯也檢查不到的。

3 異常體系結構

  Java把異常當作對象來處理,並定義了一個基類java.lang.Throwable作爲所有異常的超類。異常類分類兩大類:錯誤(Error)和異常(Exception)

3.1 錯誤(Error)

  • Error類對象由Java虛擬機生成並拋出,大多數錯誤與代碼編寫者所執行的操作無關。
  • Java虛擬機運行錯誤(Virtual MachineError),當JVM不再有繼續執行操作所需的內存資源時(溢出),將出現OutMemoryError。這些異常發生時,JVM一般會選擇線程終止。
  • 虛擬機試圖執行應用時的錯誤,如類定義錯誤(NoClassDefFoundError)、鏈接錯誤(LinkageError)。這些錯誤是不可查的,因爲它們在應用程序的控制和處理能力之外,而且絕大多數是程序運行時不允許出現的狀況。

3.2 運行時異常(RuntimeException)

名稱 描述
ArrayIndexOutOfBoundsException 數組下標越界
NullPointerException 空指針異常
ArithmeticException 算術異常
MissingResourceException 丟失資源
ClassNotFoundException 找不到類異常

這些異常一般由程序邏輯錯誤引起的,是不檢查異常,程序中可以選擇捕獲處理,也可以不處理。

  Error和Exception的區別:Error通常是災難性的致命的錯誤,是程序無法控制和處理的,當出現這些異常時,JVM一般會選擇終止線程,Exception通常情況下是可以被程序處理的,並且在程序中應該儘可能的去處理這些異常。

4 異常處理機制

異常處理的五個關鍵字:trycatchfinallythrowthrows

4.1 捕獲異常

public static void main(String[] args) {
        int a = 1;
        int b = 0;    
        try {//監控區域
            System.out.println(a / b);
        } catch (ArithmeticException e) {//catch(想要捕獲的異常類) 捕獲異常
            System.out.println("程序出現異常,變量b不能爲0");
        } finally {//處理善後,例如關閉IO流,資源等
            System.out.println("finally");
        }
}

運行結果:

程序出現異常,變量b不能爲0
finally
  • try區域是監控區域,用於需要異常處理的代碼塊。
  • catch區域是異常捕獲區域,參數爲需要捕捉的異常類型,可以進行相關的異常處理。
  • finally區域是最終處理區域,無論try區域內部的代碼是否存在異常都會執行,一般用於釋放資源。
  • trycatch兩個區域必須存在,finally區域可有可無,根據實際情況判斷。

4.2 拋出異常

public static void main(String[] args) {
        int a = 1;
        int b = 0;        
        try {
            if (b == 0) {//主動拋出異常
                throw new ArithmeticException();
            }
            System.out.println(a / b);
        } catch (Exception e) {
            System.out.println("exception");
            e.printStackTrace();//打印錯誤的棧信息
        }
}

運行結果:

exception
java.lang.ArithmeticException
	at com.base.J_ErrorException.Demo2.main(Demo2.java:10)
  • 當我們知道程序會存在某種異常時,可以使用throw關鍵字在方法內部拋出異常。
  • 可以使用printStackTrace()方法在控制檯打印異常捕獲信息
public static void main(String[] args) {
    try {
        new Demo3().test(1, 0);
    }catch (ArithmeticException e){
        System.out.println("捕捉到異常");
        e.printStackTrace();
    }
}

public void test(int a, int b) throws ArithmeticException{
	System.out.println(a / b);
}
  • throws 關鍵字用於聲明方法可能存在的異常,使用者調用該方法時,應作對應的異常捕獲處理。

5 自定義異常

使用Java內置的異常類可以描述在編程時出現的大部分異常情況,除此之外,用戶可以自定義異常類,只需要繼承Exception類即可。

/**
 * 傳遞值不能大於10的自定義異常類
 */
public class MyException extends Exception{    
    private int detail;
    public MyException(int a) {
        this.detail = a;
    }
    @Override
    public String toString() {//異常的打印信息
        return "MyException{" +
                "detail=" + detail +
                '}';
    }
}
//測試
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(e);
        }
    }
}

運行結果:

傳出的參數爲:11
MyException{detail=11}
	at com.base.J_ErrorException.Test.test(MyException.java:27)
	at com.base.J_ErrorException.Test.main(MyException.java:34)

編寫步驟:

  • 創建自定義異常
  • 在方法中通過throw關鍵字拋出異常對象
  • 如果在當前拋出的異常方法中處理異常,可以使用try-catch語句捕獲並處理異常;否則在方法的聲明出通過throws關鍵字指明要拋出給方法調用者的異常,繼續進行下一步操作。
  • 在出現異常方法的調用者中捕獲並處理異常。

6 總結

  • 處理運行時異常時,採用邏輯去合理規避同時輔助try-catch處理。
  • 在多重catch塊後面,可以加一個catch(Exception)來處理可能會被遺漏的異常。
  • 對於不確定的代碼,也可以加上try-catch,處理潛在的異常。
  • 儘量去處理異常,切忌只是簡單地調用printStackTrace()去打印輸出
  • 具體如何處理異常,要根據不同的業務需求和異常類型去決定
  • 儘量添加finally語句塊去釋放佔用的資源。


時間:2020年7月3日17:15:21


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