下圖顯示了Java異常類型層次結(jié)構(gòu):
Throwable | | +---Exception. | | | | | +--- RuntimeException | +---Error
異常及其子類用于用戶程序應(yīng)捕獲的異常條件。您可以子類化Exception以創(chuàng)建自己的自定義異常類型。
錯(cuò)誤定義在正常情況下不期望捕獲的異常。 Java運(yùn)行時(shí)系統(tǒng)使用錯(cuò)誤以指示運(yùn)行時(shí)環(huán)境中的錯(cuò)誤。 堆棧溢出是這種錯(cuò)誤的一個(gè)例子。
這個(gè)小程序包括一個(gè)有意造成除以零誤差的表達(dá)式:
public class Main { public static void main(String args[]) { int d = 0; int a = 42 / d; } }
以下是執(zhí)行此示例時(shí)生成的異常:
這里是另一個(gè)版本的前面的程序,引入相同的錯(cuò)誤,但在一個(gè)方法與main()分開:
public class Main { static void subroutine() { int d = 0; int a = 10 / d; } public static void main(String args[]) { subroutine(); } }
從默認(rèn)異常處理程序生成的堆棧跟蹤顯示如何顯示整個(gè)調(diào)用堆棧:
您可以在println()語句中顯示異常描述消息。
例如,catch塊可以這樣寫:
import java.util.Random; public class Main { public static void main(String args[]) { int a = 0, b = 0, c = 0; Random r = new Random(); for (int i = 0; i < 32000; i++) { try { b = r.nextInt(); c = r.nextInt(); a = 12345 / (b / c); } catch (ArithmeticException e) { System.out.println("Exception: " + e); a = 0; // set a to zero and continue } System.out.println("a: " + a); } } }
上面的代碼生成以下結(jié)果。
子類化RuntimeException的異常不需要包含在任何方法的throws列表中。這些被稱為未檢查異常。
java.lang中定義的未檢查異常在下表中列出。
異常 | 含義 |
---|---|
ArithmeticException | 算術(shù)錯(cuò)誤,如除以零。 |
ArrayIndexOutOfBoundsException | 數(shù)組索引超出邊界。 |
ArrayStoreException | 分配給不兼容類型的數(shù)組元素。 |
ClassCastException | 投射無效。 |
EnumConstantNotPresentException | 嘗試使用未定義的枚舉值。 |
IllegalArgumentException | 用于調(diào)用方法的非法參數(shù)。 |
IllegalMonitorStateException | 非法監(jiān)視器操作,例如等待解鎖的線程。 |
IllegalStateException | 環(huán)境或應(yīng)用程序狀態(tài)不正確。 |
IllegalThreadStateException | 請(qǐng)求的操作與當(dāng)前線程狀態(tài)不兼容。 |
IndexOutOfBoundsException | 一些類型的索引是超出界限的。 |
NegativeArraySizeException | 使用負(fù)尺寸創(chuàng)建的數(shù)組。 |
NullPointerException | 無效引用的使用無效。 |
NumberFormatException | 字符串到數(shù)字格式的轉(zhuǎn)換無效。 |
SecurityException | 試圖違反安全。 |
StringIndexOutOfBounds | 嘗試在字符串的邊界之外建立索引。 |
TypeNotPresentException | 未找到類型。 |
UnsupportedOperationException | 遇到不支持的操作。 |
檢查的異常在下表中列出。
異常 | 含義 |
---|---|
ClassNotFoundException | 找不到類。 |
CloneNotSupportedException | 嘗試克隆不實(shí)現(xiàn)Cloneable接口的對(duì)象。 |
IllegalAccessException | 對(duì)類的訪問被拒絕。 |
InstantiationException | 嘗試創(chuàng)建抽象類或接口的對(duì)象。 |
InterruptedException | 一個(gè)線程已被另一個(gè)線程中斷。 |
NoSuchFieldException | 請(qǐng)求的字段不存在。 |
NoSuchMethodException | 請(qǐng)求的方法不存在。 |
您可以通過定義 Exception
的子類來創(chuàng)建自己的異常類。
異常
類沒有定義自己的任何方法。它繼承由 Throwable
提供的方法。
以下程序創(chuàng)建自定義異常類型。
class MyException extends Exception { private int detail; MyException(int a) { detail = a; } public String toString() { return "MyException[" + detail + "]"; } } public class Main { static void compute(int a) throws MyException { System.out.println("Called compute(" + a + ")"); if (a > 10) throw new MyException(a); System.out.println("Normal exit"); } public static void main(String args[]) { try { compute(1); compute(20); } catch (MyException e) { System.out.println("Caught " + e); } } }
上面的代碼生成以下結(jié)果。
鏈接異常允許您將另一個(gè)異常與異常相關(guān)聯(lián)。第二個(gè)異常描述了第一個(gè)異常的原因。
為了允許鏈接異常,兩個(gè)構(gòu)造函數(shù)和兩個(gè)方法被添加到 Throwable
。
Throwable(Throwable causeExc) Throwable(String msg, Throwable causeExc)
這里是一個(gè)例子,說明處理鏈接異常的機(jī)制:
public class Main { static void demoproc() { NullPointerException e = new NullPointerException("top layer"); e.initCause(new ArithmeticException("cause")); throw e; } public static void main(String args[]) { try { demoproc(); } catch (NullPointerException e) { System.out.println("Caught: " + e); System.out.println("Original cause: " + e.getCause()); } } }
上面的代碼生成以下結(jié)果。
更多建議: