異常體系總覽
Java 異常繼承樹:
Throwable
├── Error // 嚴重系統錯誤,通常不可恢復
│ ├── OutOfMemoryError
│ ├── StackOverflowError
│ ├── NoClassDefFoundError
│ └── ...
└── Exception // 程式可捕獲處理
├── RuntimeException // 非檢查型異常(Unchecked)
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ ├── ClassCastException
│ ├── IllegalArgumentException
│ └── ...
└── Checked Exceptions // 檢查型異常(需 try-catch 或 throws)
├── IOException
├── SQLException
├── ClassNotFoundException
└── ...
高頻 RuntimeException(非檢查型)
| 異常 | 成因 | 預防/處理 |
| NullPointerException | 對 null 物件呼叫方法/存取欄位 | 防禦性檢查、Optional、Objects.requireNonNull |
| ArrayIndexOutOfBoundsException | 索引 < 0 或 >= length | 迴圈邊界檢查、foreach、List 替代陣列 |
| ClassCastException | 強制轉型失敗(非父子關係) | instanceof 檢查、泛型、避免原始型別 |
| IllegalArgumentException | 方法參數不合法 | 參數驗證、@NotNull、斷言 |
| NumberFormatException | 字串無法解析為數字 | try-catch、正則預檢、NumberUtils |
| ArithmeticException | 數學運算異常(如除零) | 分母檢查、BigDecimal 精確運算 |
| IndexOutOfBoundsException | List/String 索引越界 | size() 檢查、substring 邊界 |
| ConcurrentModificationException | 迭代中修改集合 | Iterator.remove、CopyOnWriteArrayList、Stream |
常見 Checked Exception(檢查型)
| 異常 | 典型場景 | 處理策略 |
| IOException | 檔案/網路/資料庫 IO 失敗 | try-with-resources、重試機制、記錄日誌 |
| SQLException | 資料庫操作失敗 | 連線池、事務管理、轉換為自訂異常 |
| ClassNotFoundException | 動態載入類別失敗 | 檢查 classpath、模組依賴、SPI 配置 |
| InterruptedException | 執行緒睡眠/等待被中斷 | 恢復中斷狀態、Thread.currentThread().interrupt() |
| NoSuchMethodException | 反射找不到方法 | 版本相容性檢查、快取 Method 物件 |
關鍵 Error(通常不捕獲)
| Error | 含義 | 應對 |
| OutOfMemoryError | 堆/元空間耗盡 | 記憶體分析、調大 -Xmx、修復洩漏 |
| StackOverflowError | 遞迴過深/無限遞迴 | 改迭代、增加 -Xss、尾遞迴優化 |
| NoClassDefFoundError | 執行期找不到類別定義 | 依賴衝突、類別載入器問題、打包檢查 |
| UnsupportedClassVersionError | 類別版本高於 JVM 支援 | 升級 JDK、降低編譯目標版本 |
異常處理黃金法則
- 具體優於通用:捕獲精確異常,避免
catch (Exception e) 吞噬錯誤。
- 異常鏈保留:
throw new CustomException("msg", cause) 保留堆疊追蹤。
- 資源確實釋放:
try-with-resources(JDK 7+)自動關閉 AutoCloseable。
- 不以控制流程:異常僅用於異常狀況,非業務邏輯分支。
- 自訂異常:繼承
RuntimeException 或 Exception,攜帶錯誤碼、上下文資訊。
快速除錯技巧
e.printStackTrace() → 生產環境改用 logger.error("", e)。
- IDE 設定 Exception Breakpoint(
NullPointerException 等)直接中斷源頭。
- 線上診斷:
jstack、jmap、Arthas、Async-profiler。
總結
熟悉異常分類、成因與處理模式,是寫出健壯 Java 程式的基石。建議將本表收藏,遇到異常快速對照定位根因,並遵循「具體捕獲、保留鏈路、資源安全」原則。