異常處理是 Java 程式健壯性的基石。本文系統梳理 Java 異常體系,涵蓋 **RuntimeException、受檢異常、Error** 三大類,附帶觸發場景、排查思路與預防最佳實踐。
Throwable
├── Error (嚴重錯誤,程式不應捕獲)
│ ├── OutOfMemoryError
│ ├── StackOverflowError
│ ├── NoClassDefFoundError
│ └── ...
└── Exception
├── RuntimeException (非受檢,編譯期不強制處理)
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ ├── ClassCastException
│ ├── IllegalArgumentException
│ ├── NumberFormatException
│ └── ...
└── 受檢異常 (編譯期強制 try-catch 或 throws)
├── IOException
├── SQLException
├── ClassNotFoundException
├── InterruptedException
└── ...
| 異常 | 觸發場景 | 核心原因 | 預防措施 |
|---|---|---|---|
| NullPointerException | 呼叫 null 物件方法、存取 null 陣列元素、拋出 null | 未檢查物件是否為 null | Objects.requireNonNull()、Optional、註解 @NonNull、防禦性程式設計 |
| ArrayIndexOutOfBoundsException | 索引 < 0 或 >= length | 迴圈邊界錯誤、動態索引未驗證 | 增強 for 迴圈、邊界檢查、List 替代陣列 |
| ClassCastException | 強制轉型失敗,如 List 轉 Set | 型別假設錯誤、泛型擦除導致執行期型別不符 | instanceof 檢查、泛型約束、編譯期檢查 |
| IllegalArgumentException | 方法參數不合法,如負數傳給需正數的參數 | 呼叫端未驗證參數 | 參數驗證框架、Guava Preconditions、Bean Validation |
| NumberFormatException | 字串解析數字失敗,如 "abc" → int | 輸入格式不符預期 | 正則預驗證、try-catch 包裹、輸入清洗 |
| IndexOutOfBoundsException | String、List、Vector 索引越界 | 同陣列越界 | size() 檢查、isEmpty() 判斷 |
| ConcurrentModificationException | 迭代過程中結構性修改集合 | 單執行緒下迭代器檢測 modCount 變化 | Iterator.remove()、CopyOnWriteArrayList、流式處理 |
FileNotFoundException:檔案不存在、權限不足、路徑為目錄EOFException:讀取到檔案末尾SocketException:網路連線異常斷開策略:`try-with-resources` 確保關閉、區分暫時性/永久性錯誤、重試機制(指數退避)。
策略:連線池管理、PreparedStatement 防注入、事務邊界清晰、錯誤碼分類處理。
| 異常 | 性質 | 觸發時機 | 典型原因 |
|---|---|---|---|
| ClassNotFoundException | 受檢異常 | Class.forName()、ClassLoader.loadClass() | 類路徑缺少 JAR、拼寫錯誤 |
| NoClassDefFoundError | Error | JVM 載入類時找不到定義 | 編譯時存在但執行時缺失、靜態初始化失敗 |
Java heap space → 堆記憶體不足:增大 -Xmx、檢查記憶體洩漏、優化大物件 Metaspace → 元空間不足:增大 -XX:MaxMetaspaceSize、類載入洩漏 GC overhead limit exceeded → GC 回收極少但頻繁:記憶體極小或洩漏 Unable to create native thread → 線程過多:減少 -Xss、線程池限制、檢查洩漏
NPE → 檢查 null、用 Optional AIOOBE → 檢查索引邊界、用 foreach CCE → instanceof 守衛、泛型設計 IAE → 參數前置驗證、Preconditions NFE → 字串解析前正則校驗 CME → 迭代器 remove、並發集合、Stream OOME → 分析 Heap Dump、調整 JVM 參數、修復洩漏 SOFE → 遞歸改迭代、檢查循環依賴 ClassNotFound → 檢查 classpath、Maven 依賴 NoClassDefFound → 檢查靜態初始化、版本衝突
異常不是敵人,而是系統健康狀態的信號。建立分層異常體系、採用結構化錯誤處理、配合監控告警,讓異常成為快速定位問題的利器,而非令人頭痛的 Bug 來源。