Java 異常體系中,Error 代表嚴重系統錯誤(如 OutOfMemoryError, StackOverflowError),通常**不建議**應用程式捕獲處理。但若確有需求(如日誌記錄、優雅關閉、防禦性框架代碼),可捕獲 Throwable 以同時涵蓋 Exception 與 Error。
public class CatchErrorDemo extends Error {
private static final long serialVersionUID = -351488225420878020L;
public CatchErrorDemo() { super(); }
public CatchErrorDemo(String msg) { super(msg); }
public static void main(String[] args) {
try {
throw new CatchErrorDemo("test catch error");
} catch (Throwable t) { // 捕獲 Throwable 才能接住 Error
System.out.println("step in the catch ~");
t.printStackTrace();
}
}
}
step in the catch ~
CatchErrorDemo: test catch error
at CatchErrorDemo.main(CatchErrorDemo.java:23)
| 捕獲類型 | 能捕獲 Exception | 能捕獲 Error | 適用場景 |
|---|---|---|---|
catch (Exception e) | ✅ | ❌ | 99% 業務代碼標準做法 |
catch (Error e) | ❌ | ✅ | 極少見,僅特定框架層 |
catch (Throwable t) | ✅ | ✅ | 頂層防禦、日誌攔截、線程池任務包裝 |
catch (Throwable):可能吞噬 ThreadDeath、OutOfMemoryError 導致系統無法正常崩潰重啟。ThreadPoolExecutor.afterExecute、Servlet Filter、AOP 切面等「最後防線」捕獲 Throwable 記錄日誌並決定是否重拋。finally 或 try-with-resources 確保資源釋放。logger.error("msg", t) 而非 logger.error(t.getMessage())。OutOfMemoryError:堆/元空間耗盡,通常不可恢復。StackOverflowError:遞迴過深或循環呼叫。NoClassDefFoundError:執行時找不到類別(版本衝突/類別載入器問題)。UnsupportedClassVersionError:類別檔版本高於 JVM 版本。