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

Java 異常處理陷阱:finally 中 return 會「吞噬」異常

     編輯:Java 相關知識

核心結論先行

在 finally 塊中使用 return、continue、break 等跳轉語句,會導致 try/catch 中拋出的異常被「吞噬」,外層調用者無法感知異常發生。

經典反面教材

public class TryTest {
    public static boolean test() throws Exception {
        try {
            throw new Exception("Something error");  // ① 拋出異常
        } catch (Exception e) {                      // ② 捕獲異常
            System.out.println("Exception from e");
            return false;                            // ⑤ 本應返回 false
        } finally {
            return true;                             // ④ 直接返回 true,「吃掉」異常
        }
    }

    public static void main(String[] args) {
        System.out.println(TryTest.test());  // 輸出:true —— 異常無聲無息消失!
    }
}

執行順序圖解

  1. try 拋出異常
  2. catch 匹配,進入塊體
  3. 打印日誌
  4. 遇到 return false,暫存返回值,控制權轉移至 finally
  5. finally 執行 return true,**直接覆蓋**暫存值並終止方法
  6. 異常未向上拋出,調用者以為一切正常

正確模式:finally 僅做清理

public static void doThings(int i) {
    try {
        if (i == 0) {
            return;  // ① 遇到 return,先暫存,執行 finally
        }
        int t = 100 / i;
        System.out.println(t);
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        System.out.println("finally");  // ② 僅做資源釋放、日誌記錄,絕不 return/throw
    }
}

最佳實踐清單

場景正確做法錯誤示範
資源關閉(流、連接、鎖)finally { if (res != null) res.close(); }finally { return; }
事務回滾finally { if (tx != null) tx.rollback(); }finally { throw new RuntimeException(); }
需返回計算結果在 try/catch 中賦值變量,finally 後統一 return result在 finally 中直接 return

進階:try-with-resources(JDK 7+)

實現 AutoCloseable 的資源,優先使用 try-with-resources,編譯器自動生成安全的 finally 邏輯,且異常不會被吞噬:

// 自動關閉,異常保留(被抑制異常可通過 getSuppressed() 獲取)
try (Connection conn = dataSource.getConnection();
     PreparedStatement ps = conn.prepareStatement(sql)) {
    // 業務邏輯
} catch (SQLException e) {
    // 異常正常拋出
    throw new RuntimeException(e);
}

總結

finally 的設計初衷是保證清理代碼必執行,而非改變方法控制流。牢記:「finally 不 return,不 throw,不 continue/break」,配合 try-with-resources,將異常處理變得既安全又優雅。

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