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

Java 異常體系深度解析:為什麼 Error 不應被捕獲?

     編輯:Java 相關知識

異常體系速覽

Throwable
├── Error          // 嚴重錯誤,JVM 層面,不可恢復
└── Exception      // 程序可處理的異常
    ├── RuntimeException  // 非受檢異常(Unchecked)
    └── 其他 Exception    // 受檢異常(Checked)

Checked vs Unchecked 異常

維度Checked ExceptionUnchecked Exception (RuntimeException)
編譯器檢查強制捕獲或拋出不強制
典型例子IOException, SQLException, ClassNotFoundExceptionNullPointerException, IndexOutOfBoundsException, ArithmeticException
發生階段編譯期可預知運行期才能確定
處理策略try-catch 或 throws 傳遞修復代碼邏輯預防

設計初衷:Java 強制處理 Checked 異常,旨在提高程序健壯性;RuntimeException 多為編程錯誤,應通過代碼修正避免,而非捕獲掩蓋。

Error 為什麼不應捕獲?

1. 本質不同:系統級災難 vs 應用級異常

  • OutOfMemoryError:堆內存耗盡,GC 無法回收。
  • StackOverflowError:棧溢出,遞歸過深。
  • NoClassDefFoundError:類加載失敗。
  • VirtualMachineError:JVM 內部錯誤。

這些錯誤表示運行環境已不可用,捕獲後也無法恢復正常業務邏輯。

2. 捕獲無意義,甚至有害

try {
    // 業務代碼
} catch (Error e) {
    log.error("捕獲 Error", e); // 日誌記錄後怎麼辦?繼續跑?重試?都無意義
}
  • 無法恢復:內存耗盡時,catch 塊本身可能無法執行(無內存創建異常對象、字符串)。
  • 掩蓋根因:吞掉 Error 會導致 JVM 狀態不可控,延遲崩潰,增加排查難度。
  • 線程安全:Error 可能在任何線程拋出,捕獲點未必是發生點。

3. 正確姿勢:預防與監控

  1. 預防:合理設置 -Xmx、-Xss;避免內存洩漏、無限遞歸。
  2. 監控:配置 JVM 參數 -XX:+HeapDumpOnOutOfMemoryError、接入 APM 監控(如 SkyWalking、Prometheus)。
  3. 容器層面:K8s 設置 livenessProbe、資源限制,讓 Pod 重啟而非進程掛起。

特殊場景:框架/容器的頂層兜底

Web 容器(Tomcat、Jetty)、框架(Spring、Netty)會在頂層捕獲 Throwable,執行:

  • 記錄完整堆疊
  • 返回 500 錯誤頁/JSON
  • 釋放請求資源(數據庫連接、線程池)
  • 標記請求失敗,不影響其他請求

這屬於基礎設施代碼,業務代碼絕不應模仿。

總結

Error 表示 JVM 不再能夠正常運行,捕獲它無法解決問題,只會掩蓋問題。正確做法是:預防發生、監控發現、容器隔離、讓進程快速失敗重啟。

業務代碼中:

  • 捕獲具體 Checked Exception(IOException 等)
  • 捕獲具體 RuntimeException(如業務邏輯預期的異常)
  • 絕不捕獲 Error 或 Throwable
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved