| 關鍵字 | 作用 | 位置 |
try | 包裹監視代碼塊 | 方法體 |
catch | 捕獲並處理異常 | try 後,可多個 |
finally | 無論是否異常必執行 | catch 後,最多一個 |
throw | 拋出異常對象 | 方法體內 |
throws | 聲明方法可能拋出的異常類型 | 方法簽名後 |
throw vs throws 速記
// throw: 拋出對象,方法體內
throw new ArithmeticException();
// throws: 聲明類型,方法簽名後
public void test() throws IOException, ArrayIndexOutOfBoundsException { ... }
捕獲匹配機制
- 多
catch 由上至下匹配,**首個匹配執行**,其餘跳過
- 捕獲變量引用指向匹配異常對象,塊內可直接使用
- 建議:具體異常在前,父類異常在後
finally 執行規則與陷阱
- 先於 return 執行,無論位置順序、是否發生異常
- 唯一不執行情況:
System.exit() 終止 JVM
- 陷阱:
finally 中修改變量**不影響** return 返回值(值在 finally 前已壓棧),**禁止在 finally 中使用 return**
try { return 1; } finally { result = 2; } // 返回仍為 1
異常體系架構

| 類別 | 特點 | 處理要求 |
Throwable | 所有錯誤/異常超類 | 只能拋出其實例 |
Error | 嚴重問題(OOM、VM錯誤),程序無法恢復 | **無需捕獲/聲明**,編譯器不檢查 |
Exception | 程序可處理的異常 | 需捕獲或聲明 |
RuntimeException | 運行時異常(空指針、越界、除零等) | **無需捕獲/聲明**,編譯器不檢查,應通過改進代碼避免 |
ThreadDeath | Thread.stop() 產生 | 捕獲後**必須重新拋出**,否則線程無法真正終止 |
兩類異常處理策略
- 運行時異常:開發調試階段盡量避免,發現即修正代碼邏輯,**不建議用 try-catch 掩蓋**
- 受檢查異常:老實處理——
try-catch 解決或 throws 傳遞
- Error:代碼不處理,排查環境/配置/資源問題
異常傳播與棧幀回溯
- 方法調用鏈中,JVM 從拋出點向回尋找處理塊
- 若回溯至
main() 仍無處理:
- 調用
printStackTrace() 輸出棧信息
- 主線程異常 → 程序終止;非主線程 → 僅終止該線程
- **原則**:越早處理,資源消耗越小,影響範圍越窄
自定義異常與異常鏈
// 自定義異常
class MyException extends Exception {
public MyException() { super("除數不能為負"); }
}
// 異常鏈 (JDK 1.4+)
throw new MyException("業務失敗", originalCause); // 封裝原始原因
// 構造方法:Throwable(String, Throwable)、Throwable(Throwable)
// 關鍵方法:getCause()、initCause(Throwable)
目的:保留原始異常堆棧,快速定位根因。
語法規則速查
try 不能單獨存在:try-catch-finally、try-catch、try-finally 三種合法結構
- 三塊變量作用域獨立,共享變量需定義在外部
- 多
catch 僅執行首個匹配塊
throw 後不允許緊跟語句(不可達)
- 調用拋出異常的方法:必須處理或繼續聲明拋出
判斷方法可能拋出異常的線索
- 方法聲明有
throws
- 方法體有
throw
- 調用的方法聲明有
throws
核心原則與技巧
- 避免過大
try 塊,精準包裹風險代碼
- 細化異常類型,禁用萬能
Exception
- 每
catch 處理一類異常,**不忽略**捕獲異常(至少記錄日誌)
- 自己能處理的異常**別拋給調用者**
- **勿用異常控制業務流程**,異常專為非正常情況設計
- 上一篇文章: Tomcat Web項目部署三大主流方式詳解與最佳實踐建議
- 下一篇文章: 深入探索Java熱部署:基於自定義ClassLoader與ASM字節碼修改實現類級熱替換
Copyright ©
程式碼之家 All Rights Reserved