1. 程式人生 > >Java筆記:異常處理

Java筆記:異常處理

parseint runtime pan exceptio 定義 bound 頂部 args tostring

一、基礎知識

異常是用來描述代碼中發生的異常情況的對象。當出現引起異常的情況時,就會拋出異常對象。方法可以選擇自己處理異常或繼續拋出異常。異常可以由Java運行時系統生成,也可以手動生成。由Java拋出的異常與違反語言規則或執行環境約束的基礎性錯誤有關,手動生成的異常通常用於向方法的調用者報告某些錯誤條件。

二、異常類型

所有的異常類型都是Throwable的子類。Throwable位於異常類層次的頂部,緊隨的兩個分支是Exception和Error。Exception可用於捕獲,也可用於自定義異常。Error則定義了在常規環境下不能由程序捕獲的異常,通常是為了響應災難性失敗。

三、捕獲異常

class Solution {
    public static void main(String[] args) {
        String s = "ABC";
        try {
            int a = Integer.parseInt(s);
            System.out.println(a);
        } catch (NumberFormatException exc) {
            System.out.println("Unknown integer format");
        }
    }
}

異常被拋出後,程序控制就會立刻從try轉移到catch中去。異常位置之後的語句不會執行。

import java.util.Scanner;

class Solution {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        String t = in.nextLine();
        try {
            int a = Integer.parseInt(s);
            
int b = Integer.parseInt(t); System.out.println(a / b); } catch (ArithmeticException exc) { System.out.println("Divisor cannot be 0"); } catch (NumberFormatException exc) { System.out.println("Unknown integer format"); } } }

單塊代碼可能會出現多種異常情況,可通過指定多條catch語句來捕獲所有可能出現的異常。當異常拋出時,會按順序檢查每條catch語句,直到遇到可以匹配的catch語句,之後會忽略剩余的catch語句。若異常無法遇到匹配的catch語句,將會無法被捕獲,程序會因異常而中斷。

當使用多條catch語句時,子類異常捕獲必須位於所有超類之前。若超類異常捕獲位於子類之前,那麽子類異常將永遠無法被捕獲。

四、內置異常

在Java內置的異常類中,最常用的是RuntimeException的子類。

所有方法不需要指明會拋出這些異常,稱為未經檢查的異常。

四、自定義異常

Exception類沒有定義任何方法,但繼承了Throwable提供的方法。

可通過繼承Exception來實現自定義異常,可通過重寫toString方法來修改異常描述。

import java.util.Scanner;

class MyException extends Exception {
    MyException(String msg) {
        super(msg);
    }

    @Override
    public String toString() {
        return "MyException: " + super.getMessage();
    }
}

class Solution {
    static int divide(int a, int b) throws MyException {
        if (b == 0)
            throw new MyException("Divisor cannot be 0");
        return a / b;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int a = in.nextInt();
        int b = in.nextInt();
        try {
            int res = divide(a, b);
            System.out.println(res);
        } catch (MyException exc) {
            System.out.println(exc);
        }
    }
}

五、鏈式異常

通過鏈式異常,可以為異常關聯另一個異常。第二個異常是引發第一個異常的原因,稱為引發異常或背後異常。可通過getCause方法獲取當前異常的背後異常,通過initCause或構造函數關聯背後異常,並且背後異常只能設置一次。

class Solution {
    static void throwerA() {
        IndexOutOfBoundsException exc = new IndexOutOfBoundsException("Index out of bounds");
        exc.initCause(new NullPointerException());
        throw exc;
    }

    static void throwerB() throws Exception {
        throw new Exception("Null pointer cause exception", new NullPointerException());
    }

    public static void main(String[] args) {
        try {
            throwerA();
        } catch (IndexOutOfBoundsException exc) {
            System.out.println(exc.toString());
            System.out.println(exc.getCause().toString());
        }
        try {
            throwerB();
        } catch (Exception exc) {
            System.out.println(exc.toString());
            System.out.println(exc.getCause().toString());
        }
    }
}

六、多重捕獲

可通過單獨的catch語句捕獲多個異常。

import java.util.Scanner;

class Solution {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int a = in.nextInt();
        int b = in.nextInt();
        int[] nums = {1, 2, 3};
        try {
            int res = a / b;
            nums[a] = res;
        } catch (ArithmeticException | ArrayIndexOutOfBoundsException exc) {
            System.out.println(exc.toString());
        }
    }
}

Java筆記:異常處理