程序運行時發生的錯誤事件,如除零導致 ArithmeticException。未捕獲時,線程終止,後續代碼不執行。
Throwable:頂層父類。Error:JVM 嚴重錯誤(如 OutOfMemoryError),不應捕獲。Exception:程序可處理的異常。
Exception(非 RuntimeException),編譯器強制 try-catch 或 throws。RuntimeException(如 NullPointerException),編譯器不強制處理。原則:自定義異常繼承 Exception 或 RuntimeException,不可直接繼承 Throwable。
try {
value = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
System.out.println("Ignore...");
}
System.out.println("Let's go!"); // 繼續執行
try { AgeUtils.checkAge(age); }
catch (TooYoungException e) { ... }
catch (TooOldException e) { ... }
或捕獲父類 AgeException 統一處理。Java 7+ 支持多異常合並:catch (TooYoungException | TooOldException e)。
try { return Integer.parseInt(text); }
catch (NumberFormatException e) { return 0; }
finally { System.out.println("End parse"); } // 永遠執行
將底層異常包裝為業務異常,保留原始原因:
public class ValidateException extends Exception {
public ValidateException(Exception cause) { super(cause); }
}
try { AgeUtils.checkAge(p.getAge()); }
catch (Exception e) { throw new ValidateException(e); } // 包裝
// 獲取真實原因
ValidateException wrap = ...;
Exception cause = (Exception) wrap.getCause();
五、RuntimeException 及常見子類
1. NullPointerException
調用 null 對象方法/字段觸發。預防勝於捕獲:if (obj != null) obj.method();。
2. ArrayIndexOutOfBoundsException
數組越界訪問。預防:if (arr.length > idx) ...。
六、自定義異常實戰
public class AgeException extends Exception { public AgeException(String msg) { super(msg); } }
public class TooYoungException extends AgeException { ... }
public class TooOldException extends AgeException { ... }
public class AgeUtils {
public static void checkAge(int age) throws TooYoungException, TooOldException {
if (age < 18) throw new TooYoungException("Age " + age + " too young");
if (age > 40) throw new TooOldException("Age " + age + " too old");
System.out.println("Age " + age + " OK!");
}
}
七、最佳實踐總結
- 異常用於非正常流程,不用於控制業務邏輯分支。
- 捕獲異常後必須處理(記錄、恢復、轉換、拋出),不可吞沒。
- 盡量使用具體異常類型,避免
catch (Exception e) 大籠統捕獲。
finally 用於釋放資源(流、鎖、連接)。
- 文檔化方法拋出的異常(
@throws Javadoc)。
- 非受檢異常用於編程錯誤(參數非法、狀態錯誤),受檢異常用於可恢復的業務場景。