| 分類 | 基類 | 特性 | 處理建議 |
|---|---|---|---|
| Exception (異常) | Exception | 程式邏輯可預期、可恢復的問題 | 開發人員應捕獲處理 |
| Error (錯誤) | Error | JVM/系統層級嚴重故障 (OOM、StackOverflow) | 一般不捕獲,讓程式終止 |
兩者共同繼承 Throwable。核心差異:異常是開發者可控的業務流程一部分;錯誤是系統級災難,通常無法恢復。
Exception 但非 RuntimeExceptionIOException、SQLException、ClassNotFoundExceptiontry-catch 或 throws 宣告RuntimeExceptionNullPointerException — 空指針ArrayIndexOutOfBoundsException — 索引越界ArithmeticException — 算術錯誤 (除零)IllegalArgumentException — 參數非法// 完整結構
try {
// 風險代碼
} catch (IOException e) {
// 處理 IO 異常
} catch (SQLException e) {
// 處理 SQL 異常
} finally {
// 無論是否異常都會執行 (資源釋放)
}
// Java 7+ 多重捕獲
try {
...
} catch (IOException | SQLException e) {
e.printStackTrace();
}
// try-with-resources (Java 7+ 推薦)
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line = br.readLine();
} // 自動關閉 br,無需 finally
catch (Exception e) {} 會掩蓋 Bug,至少記錄日誌try { ... } catch (SQLException e) {
throw new ServiceException("資料庫操作失敗", e); // 保留堆疊追蹤
}
try 或 catch 有 return,finally 仍會執行 (除非 System.exit)IllegalArgumentException 等// 底層異常轉為業務異常,隱藏實作細節
public User findById(Long id) {
try {
return jdbcTemplate.queryForObject(sql, mapper, id);
} catch (EmptyResultDataAccessException e) {
throw new UserNotFoundException("用戶不存在: " + id, e);
}
}
Spring @ControllerAdvice + @ExceptionHandler 統一處理,回傳標準錯誤碼與訊息。
// 錯誤示範:異常發生時 close() 不會執行
Reader r = new FileReader("f");
r.read(); r.close();
// 正確:try-with-resources
try (Reader r = new FileReader("f")) {
r.read();
}
throw e 會重置堆疊追蹤,請用 throw new RuntimeException(e) 或直接 throw e (Java 7+ 保留)finally 中再拋異常會覆蓋 try/catch 的異常serialVersionUID,否則反序列化可能拋 InvalidClassException