異常階層
Throwable
├── Error(嚴重錯誤,通常不捕捉)
└── Exception
├── RuntimeException(非受檢:NullPointerException, IndexOutOfBoundsException...)
└── 受檢異常(IOException, SQLException, ClassNotFoundException...)
基本語法結構
try {
riskyOperation();
} catch (NullPointerException e) {
// 處理特定異常
} catch (IOException e) {
// 處理 IO 異常
} catch (Exception e) {
// 捕捉其他受檢異常
} finally {
// 無論是否發生異常皆執行(關閉資源等)
}
關鍵規則
- 捕捉順序:子類別在前,父類別在後
finally 總會執行(除 System.exit() 或 JVM 崩潰)
throw new MyException() 主動拋出
- 方法宣告
throws Exception 呼叫端必須捕捉或繼續拋出
- 覆寫方法不能拋出比父類別更多的受檢異常
自訂異常類別
class MyException extends Exception {
public MyException() {}
public MyException(String msg) { super(msg); }
}
// 使用
public void doSomething() throws MyException {
if (badCondition) throw new MyException("錯誤原因");
}
常見陷阱
- 在
catch 中拋出新異常時,原始堆疊追蹤可能遺失(建議用 throw new NewException(original) 保留因果鏈)
- 過度使用異常控制流程(效能差),可預測情況用條件判斷
catch (Exception e) {} 吞沒異常,導致除錯困難
Java 7+ 多重捕捉
try { ... }
catch (IOException | SQLException e) {
// 同時處理多種異常
}