Java 異常處理核心在於 try-catch 結構。每個 catch 區塊就是一個「異常處理器」,專責處理特定類型的異常。本文將剖析處理器的匹配規則、執行流程,並對比兩種基本的異常處理哲學:終止模式(Java/C++ 採用)與恢復模式,探討為何現代語言多傾向終止模式。
try {
// 可能拋出異常的程式碼
} catch (Type1 id1) {
// 處理 Type1 及其子類異常
} catch (Type2 id2) {
// 處理 Type2 及其子類異常
} catch (Type3 id3) {
// 處理 Type3 及其子類異常
}
關鍵規則:
catch(參數型別為拋出異常型別或其父類),找到即執行,後續 catch 全部略過switch 不同,不需要 break,只會執行一個 catch 區塊id1 等同區域變數,可在區塊內存取異常物件;若不需使用仍必須宣告catch 必須直接跟在 try 區塊之後,中間不可插入其他陳述式try 區塊內可包含多個方法呼叫,只要它們拋出相同異常型別(或共同父類),單一 catch 即可統一處理,避免重複程式碼:
try {
methodA(); // 可能拋 IOException
methodB(); // 可能拋 IOException
methodC(); // 可能拋 IOException
} catch (IOException e) {
// 統一處理三個呼叫的 I/O 錯誤
}
try 包在 while 迴圈,成功才 break雖 Java 採終止模式,但可透過以下模式達到類似效果:
int maxRetries = 3;
for (int attempt = 1; ; attempt++) {
try {
riskyOperation();
break; // 成功跳出
} catch (TransientException e) {
if (attempt >= maxRetries) throw e; // 耗盡重試次數,向上拋出
sleep(1000 * attempt); // 指數退避
}
}
while (true) {
try {
processOrder(order);
break;
} catch (InsufficientInventoryException e) {
restock(e.getProductId()); // 修正外部狀態
// 迴圈繼續,自動重試
}
}
| 維度 | 終止模式 (Java) | 恢復模式 (理論) |
|---|---|---|
| 控制流 | 單向:拋出 → 處理 → 結束/向上拋出 | 雙向:拋出 → 處理 → 返回拋出點 |
| 錯誤嚴重度 | 假設嚴重,不可原地修復 | 假設可修復 |
| 耦合度 | 低:處理器無需知曉拋出點細節 | 高:處理器需理解拋出點上下文 |
| 程式複雜度 | 低 | 高 |
| 適用場景 | 大多數應用錯誤 | 極少數可自動修復的暫時性故障 |
Java 堅定選擇終止模式,配合 finally 保證資源釋放、try-with-resources 自動管理,構建出清晰、可靠的錯誤處理框架。理解這設計哲學,能幫你寫出更符合語言慣用語的異常處理程式碼。