JAVA物件導向基礎--異常

月亮警察發表於2024-03-11

一、什麼是異常

異常(Exception)指程式執行中出現的不期而至的各種狀況,如:

  • 檔案找不到
  • 網路連線失敗
  • 非法引數等

注意:異常發生在程式執行期間,它影響了正常的程式執行流程

二、異常的簡單分類:

  1. 檢查性異常:最具代表性的異常
  • 使用者錯誤或者問題引起的異常,這是程式設計師無法預見的異常,這些異常在編譯時不能被簡單地忽略
  • 例如:開啟一個不存在的檔案時,一個異常就發生了
  1. 執行時異常:可能會被程式設計師避免的異常
  • 與檢查性異常相反,執行時異常可能在編譯時被忽略
  1. 錯誤ERROR:錯誤不是異常,而是脫離程式設計師控制的問題
  • 錯誤在程式碼中通常被忽略
  • 例如:當一個棧溢位時,一個錯誤就發生了,它們在編譯時也檢查不到

三、異常體系結構

Java把異常當作物件來處理,並定義了一個基類java.lang.Throwable作為所有異常的超類

在java中 API中已經定義了許多異常類,這些異常類分為兩大類:Error(錯誤)和Exception(異常)

1、Exception

在Exception分支中有一個重要的子類RuntimeException(執行時異常),包括以下異常:

  • ArrayIndexOutOfBoundsException(陣列下標越界異常)
  • NullPointerException(空指標異常)
  • ArithmeticException(算術異常)
  • MissingResourceException(丟失資料)
  • ClassNotFoundException(找不到類)
  • UnKnownTypeException(未知型別異常)
  • IllegalArgumentException(非法引數異常)

注意:這些異常一般是由程式邏輯錯誤引起的,程式應該從邏輯角度儘可能避免這類異常的發生

2、Error

  • Error類物件由Java虛擬機器生成並丟擲,大多數錯誤與程式碼編寫者所執行的操作無關
  • Java虛擬機器執行錯誤(Virtual MachineError),當JVM不再有繼續執行操作所需的記憶體資源時,將出現OutOfMemoryError;這些異常出現時,Java虛擬機器(JVM)一般會選擇執行緒終止
  • 發生在虛擬機器試圖執行應用時,如類定義錯誤(NotClassDefFoundError)、連結錯誤(LinkageError)
    • 這些錯誤是不可查的,因為它們在應用程式的控制和處理能力之外,而且絕大多數是程式執行時不允許出現的狀況

3、Error和Exception的區別:

  • Error通常是災難性的致命的錯誤,是程式無法控制和處理的,當出現這些異常時,Java(JVM)一般會選擇終止執行緒
  • Exception通常情況下是可以被程式處理的,並且在程式中應該儘可能去處理這些異常

四、異常捕獲

關鍵字:try...catch...finally

執行以下程式碼會報錯:ArithmeticException: / by zero

  • 是Java中的一個執行時異常類,它繼承自java.long.RuntimeException類
  • 該異常表示在數學運算中發生了算術錯誤或不合法的操作。
//異常捕獲
public class Exception {
    public static void main(String[] args) {
        int a = 5;
        int b = 0;
        System.out.println(a/b);
    }
}

處理異常的方法:

public class CatchException {
    public static void main(String[] args) {
        int a = 5;
        int b = 0;
        //異常捕獲
        //可以自己寫,也可以使用快捷鍵Ctrl+Alt+T(先選中需要捕抓的語句)
        try { //監控區域
            System.out.println(a/b);
        } catch (Exception e) { //catch(捕獲的異常型別)  捕獲異常
            //e.printStackTrace();//列印錯誤的棧資訊
            System.out.println("0不能作為除數");
        } finally { //處理善後工作,無論有沒有異常都會執行(可有可無)
            System.out.println("finally");
        }
    }
}

1、多層捕獲

注意:多次捕獲異常時,需要按從低到高的異常階級來,可參考異常體系結構圖

public class CatchException_mul {
    public static void main(String[] args) {
        int a = 5;
        int b = 0;
        try {
            System.out.println(a/b);
        } catch (Error e) {
            System.out.println("Error");
        } catch (Exception e){
            System.out.println("Exception");//異常匹配成功,輸出
        }catch (Throwable t){
            System.out.println("Throwable");//Throwable最高階的異常
        }finally {
            System.out.println("finally");
        }
    }
}

執行結果如下:

2、主動丟擲異常

關鍵字:throw,throws

public class throw01 {
    public static void main(String[] args) {
        new throw01().test(5,0);
    }
    //自定義方法,丟擲異常
    public void test (int x,int y){
        if(y == 0){
            throw new ArithmeticException();//主動丟擲異常,一般在方法中使用
        }
    }
}

五、自定義異常(不常用)

使用Java內建的異常類可以描述在程式設計時出現的大部分異常情況;除此之外,使用者還可以自定義異常

注意:使用者自定義異常類,需要繼承Exception類

1、定義步驟

  1. 建立自定義異常類
  2. 在方法中透過throw關鍵字丟擲異常
  3. 如果在當前丟擲異常的方法中處理異常,可以使用try-catch語句捕獲並處理;否則在方法的宣告處透過throws關鍵字指明要拋處給方法呼叫者的異常
  4. 在出現異常方法的呼叫者中捕獲並處理異常
//自定義的異常類
//繼承Exception類
public class D_Exception extends Exception {
    //傳遞資料 > 10
    private int derail;
    //方法
    public D_Exception(int x){
        this.derail = x;
    }

    //toString:異常的列印資訊
    @Override //重寫toString()方法
    public String toString() {
        //內容自定義
        return "D_Exception{"+ derail+"}";
    }
}
//測試類
public class Application {
    //可能存在異常的方法
    //如果這裡不加throws...,則需要使用try..catch捕獲
    static void test(int x) throws D_Exception {
        System.out.println("傳遞的引數是:"+ x);
        if(x>10){
            throw new D_Exception(x);//丟擲異常
        }
        System.out.println("OK");
    }

    //main方法
    public static void main(String[] args) {
        //捕獲異常
        try {
            test(11);//11>10,輸出異常!!!
        } catch (D_Exception e) {
            //e:D_Exception中定義的異常資訊
            System.out.println("D_Exception=>"+e);//處理異常
        }
    }
}

2、經驗總結

  1. 處理執行時異常時,採用邏輯去合理規避同時用try-catch輔助處理
  2. 在多重catch塊後面,可以加一個catch(Exception) 來處理可能會被遺漏的異常
  3. 對於不確定的程式碼,也可以加上try-catch,處理潛在的異常
  4. 儘量去處理異常,切忌只是簡單地呼叫printStackTrace()去列印輸出
  5. 具體如何處理異常,要根據不同的業務需求和異常型別去決定
  6. 儘量新增finally語句塊去釋放佔用的資源(IO、Scanner.....)

相關文章