運行時異常 (RuntimeException 及其子類) 不強制捕獲,但實際開發中佔異常總量 80%+。熟悉高頻異常、成因與防範,能大幅降低線上故障率。
| 異常類 | 典型原因 | 預防/處理 |
|---|---|---|
NullPointerException | 調用 null 對象方法/屬性、訪問 null 陣列元素 | 非空判斷、Objects.requireNonNull、Optional、@NotNull 註解 |
ArrayIndexOutOfBoundsException | 陣列/列表索引 <0 或 ≥ length | 循環邊界檢查、List.get() 前驗證 size |
ClassCastException | 強制轉型失敗,物件非目標類型實例 | 轉型前 instanceof、泛型擦除導致的堆污染 |
IllegalArgumentException | 方法參數不合法(如負數、空字串) | 參數校驗、Preconditions.checkArgument、Bean Validation |
NumberFormatException | 字串解析數字失敗(含空格、非數字字符) | try-catch、正則預檢、NumberUtils.isParsable |
ArithmeticException | 整數除以零、取模零 | 除數非零檢查、BigDecimal 除法指定精度 |
IndexOutOfBoundsException | List/String/Buffer 索引越界 | 同陣列越界 |
IllegalStateException | 對象狀態不支持當前操作(如 Iterator 已耗盡再 next) | 狀態機設計、檢查前置條件 |
UnsupportedOperationException | 調用不可選操作(如 Arrays.asList().add()) | 查閱 API 文檔、用可變集合實現類 |
ConcurrentModificationException | 迭代過程中結構性修改集合 | 用 Iterator.remove()、CopyOnWriteArrayList、流式處理 |
NoSuchElementException | 迭代器/Scanner 無下一元素時調用 next() | 先 hasNext() 再 next() |
SecurityException | 違反安全管理器策略(Applet、簽名代碼) | 檢查權限配置、簽名 |
| 異常 | 場景 | 應對 |
|---|---|---|
OutOfMemoryError | 堆/元空間/線程棧/直接記憶體耗盡 | 調優 -Xmx、排查洩漏、堆轉儲分析 |
StackOverflowError | 遞歸過深、循環調用 | 改迭代、增加 -Xss、尾遞歸優化 |
NoClassDefFoundError | 類編譯存在但運行時找不到(依賴缺失、類加載器隔離) | 檢查 classpath、打包插件、模組化依賴 |
ClassNotFoundException | 反射/類加載器動態載入失敗 | 確認依賴、上下文類加載器 |
UnsatisfiedLinkError | JNI 本地方法庫找不到 | 配置 java.library.path、打包 so/dll |
IncompatibleClassChangeError | 類結構變更未重編譯依賴者(如字段 static↔non-static) | 全量重編譯、Maven clean install |
try {
risky();
} catch (NullPointerException | IllegalArgumentException e) {
log.error("業務參數異常", e); // 保留堆疊
throw new BizException("參數錯誤", e); // 包裝拋出
}
catch (Exception e) {} 絕對禁止Optional 表達可為空語義Caused by 為根因jstack 導出線程快照、jmap -histo:live 統計對象、arthas 熱點追蹤運行時異常雖不強制捕獲,卻是系統穩定性的最大殺手。建立「高頻異常清單 → 防禦性編程規範 → 統一異常處理體系 → 監控告警閉環」四層防線,將異常風險壓縮到最低。記住:**最好的異常處理是預防它發生**。