所有異常繼承自 java.lang.Throwable,分三大類:
Exception 子類(非 RuntimeException)。編譯器強制 try-catch 或 throws。例:IOException、SQLException。代表外部環境問題(檔案不存在、網路中斷)。RuntimeException 子類。編譯器不強制處理。例:NullPointerException、ArrayIndexOutOfBoundsException、IllegalArgumentException。代表程式邏輯 Bug,應修正代碼而非捕獲。Error 子類。嚴重系統級問題(OutOfMemoryError、StackOverflowError),應用程式通常無法恢復,交由 JVM/運行環境處理。try-catch-finally 包裹風險代碼。throws XxxException,讓呼叫者決定如何處理。try {
int x = (int)(Math.random()*5);
int y = (int)(Math.random()*10);
int[] z = new int[5];
System.out.println("y/x=" + (y/x));
System.out.println("z[y]=" + z[y]);
} catch (ArithmeticException e) {
System.out.println("算術異常:" + e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("索引越界:" + e.getMessage());
} finally {
System.out.println("無論如何都會執行(除非 JVM 退出)");
}
catch Exception 再 catch IOException 會報錯)。System.exit())、執行緒死亡、finally 內部拋異常、CPU 掛掉。// 定義
public class BusinessException extends Exception {
public BusinessException(String msg) { super(msg); }
}
// 拋出(標準範式:建立與拋出合一行,保留堆疊資訊)
throw new BusinessException("餘額不足");
// 方法聲明拋出
public void withdraw(double amt) throws BusinessException { ... }
try (FileInputStream fis = new FileInputStream("a.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
String line = br.readLine();
} // 自動關閉,無需 finally 手動 close
實作 AutoCloseable 的資源皆適用,程式碼更簡潔安全。
catch (Exception e) { } 是大忌,至少要 log.error。Exception 或 Throwable。throws,由最上層(Controller/服務入口)統一轉換為使用者友善訊息、記錄日誌、決定重試或回滾。throw new XxxException("msg", cause) 串聯原始原因。try-catch 判斷 Map 是否有 key)。e.printStackTrace() 卻不記錄到日誌系統。掌握異常體系與處理策略,能讓程式在面對不可預期情況時,依然保持穩健、可追蹤、易維護。