異常是程式執行過程中發生的錯誤狀況,但並非所有錯誤皆為異常。例如缺少分號屬於編譯錯誤 (java.lang.Error);以零為除數則拋出算術異常 (java.lang.ArithmeticException)。
這些異常可能源自使用者錯誤、程式邏輯錯誤或硬體/環境問題。
StackOverflowError、JVM 記憶體不足)。通常不捕獲處理,程式無法恢復。所有異常類別繼承自 java.lang.Exception,而 Exception 繼承自 Throwable。Throwable 另一子類為 Error。異常兩大主分支為 IOException 與 RuntimeException。

| 異常名稱 | 描述 |
|---|---|
| ArithmeticException | 算術條件異常,如整數除以零 |
| ArrayIndexOutOfBoundsException | 非法索引存取陣列 |
| ClassCastException | 物件強制轉型失敗 |
| IllegalArgumentException | 傳遞不合法參數給方法 |
| NullPointerException | 嘗試在需要物件處使用 null |
| NumberFormatException | 字串轉數值格式錯誤 |
| IndexOutOfBoundsException | 索引超出範圍(陣列、字串、向量) |
| NegativeArraySizeException | 建立負大小陣列 |
| SecurityException | 安全管理器偵測到安全違規 |
| StringIndexOutOfBoundsException | 字串索引超出範圍 |
| UnsupportedOperationException | 不支援的操作請求 |
| 異常名稱 | 描述 |
|---|---|
| ClassNotFoundException | 找不到指定類別 |
| CloneNotSupportedException | 物件類別未實作 Cloneable 介面 |
| IllegalAccessException | 拒絕存取類別 |
| InstantiationException | 嘗試實例化介面或抽象類別 |
| InterruptedException | 執行緒被中斷 |
| NoSuchFieldException / NoSuchMethodException | 請求的欄位/方法不存在 |
| 方法 | 說明 |
|---|---|
getMessage() | 返回異常詳細訊息 |
getCause() | 返回異常原因物件 |
toString() | 返回類別名稱 + 訊息 |
printStackTrace() | 輸出堆疊追蹤至錯誤流 |
getStackTrace() | 返回堆疊追蹤元素陣列 |
fillInStackTrace() | 用當前呼叫堆疊重填堆疊追蹤 |
try {
// 可能拋出異常的程式碼(保護碼)
} catch (ExceptionType1 e1) {
// 處理 ExceptionType1
} catch (ExceptionType2 e2) {
// 處理 ExceptionType2
} finally {
// 無論是否發生異常皆執行(資源清理)
public class ExcepTest {
public static void main(String[] args) {
try {
int[] a = new int[2];
System.out.println("Access element three: " + a[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception thrown: " + e);
}
System.out.println("Out of the block");
}
}
// 輸出:
// Exception thrown: java.lang.ArrayIndexOutOfBoundsException: 3
// Out of the block
一個 try 可跟隨多個 catch,依序比對異常型別,匹配即處理,否則傳遞下一個。注意:子類別異常必須寫在父類別之前,否則會編譯錯誤。
public void withdraw(double amount) throws RemoteException, InsufficientFundsException {
if (amount > balance) throw new InsufficientFundsException(amount - balance);
balance -= amount;
}
finally 區塊無論異常是否發生、是否被捕獲、甚至 try/catch 中有 return,總會執行(極少數情況除外,如 System.exit())。常用於關閉檔案、釋放連線等收尾工作。
catch 不能獨立存在,必須跟在 try 後。finally 非強制,但 try 後至少要有一個 catch 或 finally。try、catch、finally 之間不能插入其他程式碼。開發領域特定異常時,需遵循:
Throwable。Exception。RuntimeException。// InsufficientFundsException.java
public class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) { this.amount = amount; }
public double getAmount() { return amount; }
}
// CheckingAccount.java
public class CheckingAccount {
private double balance;
private int number;
public CheckingAccount(int number) { this.number = number; }
public void deposit(double amount) { balance += amount; }
public void withdraw(double amount) throws InsufficientFundsException {
if (amount <= balance) balance -= amount;
else throw new InsufficientFundsException(amount - balance);
}
// getters...
}
// BankDemo.java
public class BankDemo {
public static void main(String[] args) {
CheckingAccount c = new CheckingAccount(101);
c.deposit(500);
try {
c.withdraw(100);
c.withdraw(600); // 拋出異常
} catch (InsufficientFundsException e) {
System.out.println("Sorry, but you are short $" + e.getAmount());
e.printStackTrace();
}
}
}
執行結果:
Depositing $500... Withdrawing $100... Withdrawing $600... Sorry, but you are short $200.0 InsufficientFundsException at CheckingAccount.withdraw(CheckingAccount.java:25) at BankDemo.main(BankDemo.java:13)
NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException。IllegalArgumentException、IllegalStateException。掌握異常體系與處理機制,能編寫出更健壯、可維護的 Java 應用程式。