try-catch-finally 完整語法
try {
// 可能拋出異常的核心邏輯
} catch (ExceptionType1 e) {
// 處理類型 1
} catch (ExceptionType2 e) {
// 處理類型 2
} finally {
// 無論是否異常、是否 return,必執行 (清理資源)
}
捕獲順序鐵律:子類在前,父類在後
// ❌ 錯誤:Exception 捕獲所有,後續 catch 永遠不可達
try { ... }
catch (Exception e) { ... }
catch (IOException e) { ... } // 編譯錯誤
// ✅ 正確:具體異常優先
try { ... }
catch (FileNotFoundException e) { ... } // 子類
catch (IOException e) { ... } // 父類
catch (Exception e) { ... } // 總攬
多 catch 合併 (Java 7+)
try { ... }
catch (IOException | SQLException e) { // 同類處理邏輯
log.error("IO/DB 錯誤", e);
}
finally 核心價值:資源安全釋放
InputStream is = null;
try {
is = new FileInputStream("data.txt");
// 讀取邏輯
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try { is.close(); } catch (IOException ignored) {}
}
}
Java 7+ try-with-resources 取代手動 finally:
try (InputStream is = new FileInputStream("data.txt")) {
// 讀取邏輯
} catch (IOException e) {
e.printStackTrace();
} // 編譯器自動生成 finally 關閉 is
自定義異常設計規範
繼承選擇
| 繼承 | 分類 | 適用場景 | 處理強制性 |
| Exception | 受檢異常 | 業務邏輯可預期、可恢復錯誤 (餘額不足、參數非法) | 編譯強制 try-catch 或 throws |
| RuntimeException | 非受檢異常 | 程式錯誤、不可恢復 (空指針、下標越界、配置缺失) | 不強制,建議全域攔截 |
命名慣例:XxxException
// 業務異常:受檢
public class InsufficientBalanceException extends Exception {
public InsufficientBalanceException(String msg) { super(msg); }
public InsufficientBalanceException(String msg, Throwable cause) { super(msg, cause); }
}
// 系統異常:非受檢
public class ConfigLoadException extends RuntimeException {
public ConfigLoadException(String msg, Throwable cause) { super(msg, cause); }
}
四大異常處理模式
1. 就地處理
try {
int age = Integer.parseInt(input);
} catch (NumberFormatException e) {
// 直接修正/提示/預設值
age = 18;
}
適用:有足夠上下文、能立即糾正。
2. 包裝轉換
try {
// 底層 IO/DB 操作
} catch (SQLException e) {
throw new DataAccessException("用戶查詢失敗", e); // 保留原始堆疊
}
適用:分層架構,隱藏實現細節,統一上層異常類型。
3. 向上拋出
public void service() throws BusinessException {
dao.query(); // 宣稱拋出,由 Controller 處理
}
適用:當前層無法決策,交由調用者處理。
4. 記錄並吞沒 (極少用)
try { risky(); } catch (Exception e) { log.warn("非關鍵操作失敗", e); }
⚠️ 僅用於真正無影響的輔助操作(如統計上報、緩存預熱)。
避坑指南
| 反模式 | 後果 | 正解 |
| catch 為空 | 異常黑洞,排查極難 | 至少 log.error 或拋出包裝異常 |
| 用異常控制流程 | 效能差、可讀性低 | 用 if/Optional/Result 物件 |
| try 區塊過大 | JIT 優化失效、掩蓋真正風險點 | 最小化 try 範圍 |
| finally 中拋出異常 | 掩蓋原始異常 | finally 內再 try-catch |
| 捕獲 Exception/Throwable | 誤捕系統級錯誤 (OOM/StackOverflow) | 捕獲具體業務異常 |
總結
- try-catch-finally 是基礎骨架,try-with-resources 是資源管理標準。
- 異常分受檢/非受檢,自定義異常按業務語義選擇繼承鏈。
- 處理模式:就地修正、包裝轉換、向上拋出、記錄吞沒,按架構層級選擇。
- 核心原則:**異常用於「異常情況」,不用於正常流程控制;保留堆疊追蹤,精準定位根因。**
- 上一篇文章: Java IO 核心思想:流抽象屏蔽數據源差異,統一讀寫介面
- 下一篇文章: Java 異常處理基石:throw 拋出與 throws 聲明機制深度解析
Copyright ©
程式碼之家 All Rights Reserved