Java筆記:異常處理
一、基礎知識
異常是用來描述代碼中發生的異常情況的對象。當出現引起異常的情況時,就會拋出異常對象。方法可以選擇自己處理異常或繼續拋出異常。異常可以由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筆記:異常處理