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

Java 異常處理完整指南:體系、最佳實踐與自定義異常

     編輯:Java 相關知識

異常處理是編寫健壯 Java 程式的基石。本文系統梳理 Java 異常體系、內置異常類、捕獲處理機制、finally、throws/throw、自定義異常及常見陷阱,幫助開發者建立規範的異常處理體系。

異常分類:三大類別

類別代表特點處理要求
受檢異常
(Checked Exception)
IOException、ClassNotFoundException編譯期強制檢查,通常由外部因素導致(文件不存在、網絡中斷)必須 try-catch 或 throws 聲明
運行時異常
(Runtime Exception)
NullPointerException、ArrayIndexOutOfBoundsException編譯期不檢查,通常由邏輯錯誤導致(空指針、越界)建議通過代碼邏輯預防,而非單純捕獲
錯誤
(Error)
OutOfMemoryError、StackOverflowErrorJVM 層面嚴重問題,應用無法恢復一般不捕獲,需優化代碼或調優 JVM

異常類層次結構

java.lang.Throwable
├── java.lang.Error
└── java.lang.Exception
    ├── java.io.IOException
    ├── java.lang.RuntimeException
    │   ├── NullPointerException
    │   ├── IllegalArgumentException
    │   └── ...
    └── 其他受檢異常...

核心處理語法

try-catch-finally 標準模式

try {
    // 風險代碼
} catch (IOException e) {
    // 處理 IO 異常
} catch (SQLException e) {
    // 處理 SQL 異常
} finally {
    // 清理資源(關閉流、釋放鎖),無論是否異常都會執行
}

多重捕獲注意事項

  • 子類異常必須寫在父類之前,否則編譯報錯(如 FileNotFoundException 必須在 IOException 前)。
  • Java 7+ 支持多異常合併捕獲:catch (IOException | SQLException e)。

throws vs throw

  • throws:方法簽名聲明拋出的異常,將責任上傳給調用者。
  • throw:主動拋出異常實例:throw new BusinessException("餘額不足")。

finally 的關鍵作用

try {
    connection = dataSource.getConnection();
    // 業務邏輯
} catch (SQLException e) {
    log.error("數據庫操作失敗", e);
    throw new DaoException(e);
} finally {
    // 確保連接歸還池中,防止洩漏
    if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}

陷阱: finally 中使用 return 會吞噬 try/catch 中拋出的異常,切勿如此使用。

自定義異常最佳實踐

設計原則

  1. 業務異常繼承 Exception(受檢),系統/邏輯異常繼承 RuntimeException。
  2. 提供構造函數鏈:message、cause、message+cause。
  3. 攜帶業務上下文信息(如錯誤碼、參數快照)。

示例:業務異常

public class InsufficientFundsException extends Exception {
    private final double shortage;

    public InsufficientFundsException(double shortage) {
        super(String.format("餘額不足,缺口 %.2f 元", shortage));
        this.shortage = shortage;
    }

    public double getShortage() { return shortage; }
}

使用場景

public void withdraw(double amount) throws InsufficientFundsException {
    if (amount > balance) {
        throw new InsufficientFundsException(amount - balance);
    }
    balance -= amount;
}

常見內置異常速查

異常觸發場景
NullPointerException調用 null 對象方法/屬性
ClassCastException強制轉型失敗
IllegalArgumentException方法參數不合法
NumberFormatException字符串轉數字格式錯誤
IndexOutOfBoundsException數組/集合索引越界
ConcurrentModificationException迭代時併發修改集合

異常處理黃金法則

  1. 具體捕獲:捕獲具體異常類,避免 catch (Exception e) 大餐。
  2. 早拋出、晚捕獲:底層拋出,業務層統一捕獲並轉換為業務異常。
  3. 保留堆疊:拋出新異常時帶上 cause:throw new BizException("下單失敗", e)。
  4. 資源關閉:使用 try-with-resources (Java 7+) 自動關閉實現 AutoCloseable 的資源。
  5. 日誌記錄:捕獲處理後記錄完整堆疊,避免 e.printStackTrace() 直寫控制台。

總結

異常處理不是「捕獲並吞噬」,而是「識別、轉換、上下文豐富、資源安全釋放、可觀測」。建立分層異常體系(系統異常 vs 業務異常),配合全局異常處理器(如 Spring @ControllerAdvice),才能構建可維護、可排查的生產級應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved