許多開發者初學時將異常視為「錯誤」而恐懼避之,實則異常是程式運行時偵測到的異常狀況,是除錯與維護的關鍵線索。合理拋出與捕獲異常,能讓問題在第一時間浮現,大幅降低排查成本。
NullPointerException),自訂異常可攜帶上下文資訊 (方法名、參數值、業務含義)。catch 區塊) 會掩蓋 Bug,導致系統在不可預期狀態下繼續運行。public void addUser(String username, int age) {
if (username == null || username.trim().isEmpty()) {
throw new IllegalArgumentException("用戶名不能為空");
}
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年齡範圍錯誤: " + age);
}
// 業務邏輯...
}
公開方法 (Public API) 必須嚴格驗證輸入;私有方法可視情況省略。
對於可預期、可恢復的業務錯誤 (如餘額不足、庫存不足),建議定義繼承 Exception 的受檢異常,強制呼叫端處理:
public class InsufficientBalanceException extends Exception {
public InsufficientBalanceException(String message) { super(message); }
}
public void transfer(Account from, Account to, BigDecimal amount) throws InsufficientBalanceException {
if (from.getBalance().compareTo(amount) < 0) {
throw new InsufficientBalanceException("帳戶 " + from.getId() + " 餘額不足");
}
// 轉帳邏輯...
}
對於不應發生、屬於程式 Bug 的情況 (如空指標、陣列越界、非法狀態),拋出 RuntimeException 子類別 (如 IllegalStateException),讓其冒泡至全域異常處理器記錄日誌並終止流程。
| 場景 | 建議做法 |
|---|---|
| 底層工具庫 / 框架代碼 | 拋出具體異常,不要捕獲,讓上層決定如何處理 |
| 業務服務層 | 捕獲底層異常,轉換為業務異常並拋出 (異常鏈:throw new BizEx(e)) |
| 控制層 / 入口點 (Controller, main, 執行緒 run) | 統一捕獲,記錄日誌,回傳友善錯誤碼/頁面 |
new MyException("msg", cause))。catch (Exception e) 過於寬泛,應捕獲具體異常類型。AutoCloseable 的資源。異常不是敵人,而是系統健康狀態的儀表板。在邊界驗證參數、業務規則違反時主動拋出語意清晰的異常,在架構分層邊界統一處理,讓錯誤資訊精準流向最適合處理它的層級,這就是高品質 Java 異常處理的精髓。