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

Java 異常處理核心概念與最佳實踐:try-catch-finally、異常鏈與資源釋放

     編輯:Java 相關知識

異常體系概覽

Throwable
├── Error          // 嚴重錯誤(OutOfMemoryError、StackOverflowError),不可恢復,不應捕獲
└── Exception      // 可處理的異常
    ├── RuntimeException  // 非受檢異常(空指針、越界、類轉換),編譯器不強制捕獲
    └── 其他              // 受檢異常(IOException、SQLException),必須捕獲或拋出

處理語法結構

基本形式

try {
    // 風險代碼
} catch (ExceptionType1 e) {
    // 處理類型1
} catch (ExceptionType2 e) {
    // 處理類型2
} finally {
    // 無論是否異常必執行(資源清理)
}

try-with-resources (JDK 7+ 推薦)

// 自動關閉實現 AutoCloseable 的資源
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    String line = br.readLine();
} catch (IOException e) {
    e.printStackTrace();
} // br 自動 close()

異常鏈:保留原始原因

問題:異常丟失

try {
    risky();
} catch (ExceptionA e) {
    throw new ExceptionB("處理失敗"); // 原始 e 丟失!
}

解決:initCause / 構造器傳入 cause

try {
    risky();
} catch (ExceptionA e) {
    ExceptionB eb = new ExceptionB("處理失敗");
    eb.initCause(e);           // 方式1
    // 或 new ExceptionB("處理失敗", e) // 方式2(推薦)
    throw eb;
}

輸出堆疊將包含 Caused by: ExceptionA,便於根因定位。

資源清理最佳實踐

傳統 finally 模式(JDK 6 或無 AutoCloseable)

BufferedReader br = null;
try {
    br = new BufferedReader(new FileReader("file.txt"));
    // 業務邏輯
} catch (FileNotFoundException e) {
    // 處理
} finally {
    if (br != null) {
        try { br.close(); } catch (IOException ignored) {}
    }
}

資料庫連接清理範例

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
    conn = dataSource.getConnection();
    ps = conn.prepareStatement(sql);
    rs = ps.executeQuery();
    // 處理結果集
} catch (SQLException e) {
    // 記錄日誌、拋出業務異常
} finally {
    // 逆序關閉
    closeQuietly(rs);
    closeQuietly(ps);
    closeQuietly(conn);
}

常見陷阱與規範

陷阱後果規範
catch 塊為空吞噬異常,難以排查至少記錄日誌:log.error("msg", e)
捕獲 Exception/Throwable 過寬掩蓋編程錯誤(如 NPE)捕獲具體受檢異常,RuntimeException 向上拋
finally 中拋出異常覆蓋 try/catch 中的原始異常finally 內部自行 try-catch,或用 try-with-resources
異常用於流程控制性能差、可讀性低用條件判斷替代

自定義異常設計

// 業務異常:受檢,調用者必須處理
public class BusinessException extends Exception {
    private final int errorCode;
    public BusinessException(int code, String msg) { super(msg); this.errorCode = code; }
    public BusinessException(int code, String msg, Throwable cause) { super(msg, cause); this.errorCode = code; }
}

// 系統異常:非受檢,向上拋至全局處理器
public class SystemException extends RuntimeException {
    public SystemException(String msg, Throwable cause) { super(msg, cause); }
}

總結

  • 受檢異常:API 契約一部分,強制調用者處理(如 IO、SQL)。
  • 非受檢異常:編程錯誤,應修復代碼而非捕獲(如 NPE、越界)。
  • finally / try-with-resources:資源釋放的唯一可靠保障。
  • 異常鏈:永遠保留 cause,構造器傳入或 initCause。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved