首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 運行時異常大全:分類、成因與處理策略速查表

     編輯:Java 相關知識

運行時異常體系

繼承自 `RuntimeException`,編譯器不強制捕獲/聲明,但業務邏輯錯誤高發區。掌握高頻異常成因與預防模式,是寫出健壯代碼的基本功。

高頻異常分類速查表

異常類別典型成因代碼示例預防/處理策略
NullPointerException調用 null 物件方法/欄位、訪問 null 陣列元素`user.getName().length()` / `arr[0].toString()`Objects.requireNonNull、Optional、@NonNull 註解、防御性檢查
ArrayIndexOutOfBoundsException索引 < 0 或 >= length`list.get(size)` / `arr[-1]`邊界檢查、foreach/stream 替代索引、List 而非陣列
ArithmeticException整數除以零、模零`int x = 1/0; int y = 5 % 0;`除數預檢、BigDecimal 除法指定精度/模式
ClassCastException強制轉型失敗,物件非目標類型`(String) list.get(0)` 實為 Integer泛型擦除警惕、instanceof 守衛、編譯期泛型約束
IllegalArgumentException方法參數不合法(範圍、格式、狀態)`setAge(-1)` / `parse("abc")`參數驗證 (Bean Validation)、前置條件斷言
IllegalStateException物件狀態不支持當前操作`iterator.remove()` 未先 `next()` / 連接池已關閉狀態機設計、@PreAuthorize、文檔化合法狀態遷移
NumberFormatException字串無法解析為數字`Integer.parseInt("1.5")` / `Long.parseLong("abc")`正則預檢、try-catch 包裝返回 Optional、NumberUtils
UnsupportedOperationException調用不支持的可選操作`Collections.unmodifiableList.add()` / `iterator.remove()`文檔化不可變集合、介面分離 (只讀/可寫)
IndexOutOfBoundsException超出序列邊界 (List/String/Buffer)`str.charAt(len)` / `subList(0, size+1)`同 ArrayIndexOutOfBounds,邊界守衛
ConcurrentModificationException迭代過程中結構性修改集合`for (e: list) list.remove(e)`Iterator.remove、CopyOnWriteArrayList、Stream、收集後再刪

JVM/系統級嚴重錯誤

錯誤類別屬性典型場景應對
OutOfMemoryErrorError (不可恢復)堆耗盡、Metaspace 滿、直接記憶體洩漏、線程過多Heap Dump 分析 (MAT/JVisualVM)、調優 -Xmx、排查洩漏、啟用 GC 日誌
StackOverflowErrorError遞歸過深、循環調用、大棧幀 (大量局部變數)改迭代、增加 -Xss、尾遞歸優化 (JVM 不保證)
NoClassDefFoundErrorError類初始化失敗、類路徑缺失、版本衝突、靜態塊拋異常`mvn dependency:tree`、檢查類載入器、排查靜態初始化
ClassNotFoundExceptionChecked Exception反射/類載入器動態載入失敗同 NoClassDefFoundError,確認依賴打包
UnsatisfiedLinkErrorErrorJNI 本地庫找不到/版本不匹配/架構不符 (x86 vs x64)配置 java.library.path、檢查 .so/.dll 依賴

異常處理黃金法則

  1. 區分「程式錯誤」與「環境錯誤」: RuntimeException 多為程式 Bug,應修代碼而非 catch;IOException/TimeoutException 為環境錯誤,需重試/熔斷/降級。
  2. 不捕獲無法處理的異常: `catch (Exception e) { log.error }` 吞沒異常是大忌。若無法恢復,拋給上層或全局處理器。
  3. 自定義異常承載業務語義: `InsufficientBalanceException` 比 `IllegalArgumentException` 更精準,便於上層針對性處理。
  4. 保留堆疊追蹤: `throw e` 不 `throw new RuntimeException(e)` (除非轉換語義),`logger.error("msg", e)` 而非 `logger.error(e.getMessage())`。
  5. 資源必在 finally/try-with-resources 釋放: 連接、流、鎖、信號量。

實戰:全局異常處理器模板


@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(BusinessException.class)
    public R handleBiz(BusinessException e) {
        log.warn("業務異常: {}", e.getMessage());
        return R.fail(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(ConstraintViolationException.class)
    public R handleValid(ConstraintViolationException e) {
        String msg = e.getConstraintViolations().stream()
            .map(v -> v.getPropertyPath() + " " + v.getMessage())
            .collect(Collectors.joining("; "));
        return R.fail(400, msg);
    }

    @ExceptionHandler(Exception.class)
    public R handleAll(Exception e) {
        log.error("系統異常", e); // 完整堆疊
        return R.fail(500, "系統內部錯誤,請稍後重試");
    }
}

結語

異常不是敵人,是系統在說話。建立「預防 > 捕獲 > 記錄 > 告警 > 復原」的完整鏈路,比背誦異常清單更重要。下一篇將實戰《Spring Boot 3 錯誤處理機制深度解析與最佳實踐》。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved