首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 異常處理完整指南:體系架構、最佳實務與進階技巧

     編輯:Java 程式設計入門

異常與錯誤的本質區別

分類基類特性處理建議
Exception (異常)Exception程式邏輯可預期、可恢復的問題開發人員應捕獲處理
Error (錯誤)ErrorJVM/系統層級嚴重故障 (OOM、StackOverflow)一般不捕獲,讓程式終止

兩者共同繼承 Throwable。核心差異:異常是開發者可控的業務流程一部分;錯誤是系統級災難,通常無法恢復。

異常分類體系

1. 受檢異常 — 編譯期強制處理

  • 繼承 Exception 但非 RuntimeException
  • 如 IOException、SQLException、ClassNotFoundException
  • 編譯器強制 try-catch 或 throws 宣告

2. 非受檢異常 — 運行期拋出

  • 繼承 RuntimeException
  • 常見子類:
    • NullPointerException — 空指針
    • 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);  // 保留堆疊追蹤
    }
  • finally 必執行:即使 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
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved