在 Java 程式設計中,異常處理是開發者必須掌握的核心技能。Java 將異常分為兩大類:Checked Exception(受檢異常)與 Runtime Exception(執行時異常)。兩者在編譯器檢查機制、程式碼撰寫規範以及設計哲學上有著本質差異。本文將從機制層面與邏輯層面兩個維度,深入剖析這兩種異常的區別與應用場景。
java.lang.Exception(但不包含 RuntimeException 及其子類)。java.lang.RuntimeException 或 java.lang.Error。當方法可能拋出 Checked Exception 時,必須在方法簽名中使用 throws 關鍵字聲明;而 Runtime Exception 則無需聲明。
// 自訂 Checked Exception
public class CheckedException extends Exception {
public CheckedException() {}
public CheckedException(String message) { super(message); }
}
public class ExceptionalClass {
// 必須聲明拋出 CheckedException
public void method1() throws CheckedException {
// ... throw new CheckedException("...出錯了");
}
// 拋出 Runtime Exception(NullPointerException),無需聲明
public void method2(String arg) {
if (arg == null) {
throw new NullPointerException("method2的參數arg是null!");
}
}
// 未直接拋出,但調用 method1(),選擇向上傳遞
public void method3() throws CheckedException {
method1();
}
}
try-catch 捕獲,或在自身方法簽名中繼續 throws 向上傳遞。public static void main(String[] args) {
ExceptionalClass example = new ExceptionalClass();
// 必須處理 Checked Exception
try {
example.method1();
example.method3();
} catch (CheckedException ex) { /* 處理邏輯 */ }
// 無需處理 Runtime Exception,直接呼叫
example.method2(null); // 拋出 NullPointerException
}
| 特性 | Runtime Exception | Checked Exception |
|---|---|---|
| 方法定義時是否需聲明 | 不需要 | 必須聲明所有可能拋出的 checked exception |
| 呼叫時是否強制捕獲 | 不強制 | 必須捕獲或繼續向上傳遞 |
| 繼承體系 | java.lang.RuntimeException / java.lang.Error | java.lang.Exception(不含 RuntimeException 分支) |
除了語法機制,兩者的核心差異在於「異常發生時,呼叫端是否有能力恢復或處理」:
FileNotFoundException)、資料庫連線失敗(SQLException)、網路中斷。呼叫端應針對性處理:重試、提示用戶、使用備用方案等。NullPointerException)、陣列越界(ArrayIndexOutOfBoundsException)、除零錯誤(ArithmeticException)。此類錯誤應在開發階段透過單元測試、程式碼審查修正,而非在運行期靠 try-catch 掩蓋。Exception 表示可恢復業務異常;繼承 RuntimeException 表示程式錯誤或系統級不可恢復錯誤。e.printStackTrace()),必須有實質處理邏輯或轉換為更高層級的異常重新拋出。理解 Checked Exception 與 Runtime Exception 的機制與邏輯差異,能幫助我們設計出更健壯、更具可維護性的 Java 系統。記住:異常處理的核心不是「捕獲」,而是「如何讓系統在異常發生時仍能表現出可預期的行為」。