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

Java 常見異常與錯誤完整分類圖譜:從 NullPointerException 到 OutOfMemoryError

     編輯:Java 相關知識

前言

異常處理是 Java 程式健壯性的基石。本文系統梳理 Java 異常體系,涵蓋 **RuntimeException、受檢異常、Error** 三大類,附帶觸發場景、排查思路與預防最佳實踐。

一、異常體系架構速覽

Throwable
├── Error (嚴重錯誤,程式不應捕獲)
│   ├── OutOfMemoryError
│   ├── StackOverflowError
│   ├── NoClassDefFoundError
│   └── ...
└── Exception
    ├── RuntimeException (非受檢,編譯期不強制處理)
    │   ├── NullPointerException
    │   ├── ArrayIndexOutOfBoundsException
    │   ├── ClassCastException
    │   ├── IllegalArgumentException
    │   ├── NumberFormatException
    │   └── ...
    └── 受檢異常 (編譯期強制 try-catch 或 throws)
        ├── IOException
        ├── SQLException
        ├── ClassNotFoundException
        ├── InterruptedException
        └── ...

二、高頻 RuntimeException 深度解析

異常觸發場景核心原因預防措施
NullPointerException呼叫 null 物件方法、存取 null 陣列元素、拋出 null未檢查物件是否為 nullObjects.requireNonNull()、Optional、註解 @NonNull、防禦性程式設計
ArrayIndexOutOfBoundsException索引 < 0 或 >= length迴圈邊界錯誤、動態索引未驗證增強 for 迴圈、邊界檢查、List 替代陣列
ClassCastException強制轉型失敗,如 List 轉 Set型別假設錯誤、泛型擦除導致執行期型別不符instanceof 檢查、泛型約束、編譯期檢查
IllegalArgumentException方法參數不合法,如負數傳給需正數的參數呼叫端未驗證參數參數驗證框架、Guava Preconditions、Bean Validation
NumberFormatException字串解析數字失敗,如 "abc" → int輸入格式不符預期正則預驗證、try-catch 包裹、輸入清洗
IndexOutOfBoundsExceptionString、List、Vector 索引越界同陣列越界size() 檢查、isEmpty() 判斷
ConcurrentModificationException迭代過程中結構性修改集合單執行緒下迭代器檢測 modCount 變化Iterator.remove()、CopyOnWriteArrayList、流式處理

三、關鍵受檢異常處理策略

3.1 IOException 體系

  • FileNotFoundException:檔案不存在、權限不足、路徑為目錄
  • EOFException:讀取到檔案末尾
  • SocketException:網路連線異常斷開

策略:`try-with-resources` 確保關閉、區分暫時性/永久性錯誤、重試機制(指數退避)。

3.2 SQLException

  • SQL 語法錯誤、約束違反、死鎖、連線超時

策略:連線池管理、PreparedStatement 防注入、事務邊界清晰、錯誤碼分類處理。

3.3 ClassNotFoundException vs NoClassDefFoundError

異常性質觸發時機典型原因
ClassNotFoundException受檢異常Class.forName()、ClassLoader.loadClass()類路徑缺少 JAR、拼寫錯誤
NoClassDefFoundErrorErrorJVM 載入類時找不到定義編譯時存在但執行時缺失、靜態初始化失敗

四、嚴重 Error 排查指南

4.1 OutOfMemoryError

Java heap space          → 堆記憶體不足:增大 -Xmx、檢查記憶體洩漏、優化大物件
Metaspace                → 元空間不足:增大 -XX:MaxMetaspaceSize、類載入洩漏
GC overhead limit exceeded → GC 回收極少但頻繁:記憶體極小或洩漏
Unable to create native thread → 線程過多:減少 -Xss、線程池限制、檢查洩漏

4.2 StackOverflowError

  • 遞歸無終止條件、遞歸深度過大
  • 循環依賴(A→B→A)
  • 解決:遞歸改迭代、增加 -Xss、尾遞歸優化(JVM 不保證)

4.3 NoClassDefFoundError / ClassCircularityError

  • 類初始化失敗(static 區塊拋異常)
  • 循環靜態初始化依賴
  • Maven 依賴衝突、版本不一致

五、異常處理最佳實踐

  1. 具體捕獲:捕獲具體異常而非 `Exception` 或 `Throwable`
  2. 早拋出、晚捕獲:底層拋出,業務層統一處理
  3. 保留堆疊追蹤:`throw e` 而非 `throw new Exception(e)`;包裝異常用 `throw new BizException("msg", e)`
  4. 資源釋放用 try-with-resources:自動關閉實作 AutoCloseable 的資源
  5. 自訂異常區分業務錯誤碼:繼承 RuntimeException,攜帶 errorCode、params
  6. 全域異常處理器:`@ControllerAdvice` + `@ExceptionHandler` 統一返回結構化錯誤響應
  7. 日誌記錄原則:ERROR 級別記錄完整堆疊、WARN 記錄業務異常、避免重複記錄

六、快速查閱卡片

NPE          → 檢查 null、用 Optional
AIOOBE       → 檢查索引邊界、用 foreach
CCE          → instanceof 守衛、泛型設計
IAE          → 參數前置驗證、Preconditions
NFE          → 字串解析前正則校驗
CME          → 迭代器 remove、並發集合、Stream
OOME         → 分析 Heap Dump、調整 JVM 參數、修復洩漏
SOFE         → 遞歸改迭代、檢查循環依賴
ClassNotFound → 檢查 classpath、Maven 依賴
NoClassDefFound → 檢查靜態初始化、版本衝突

總結

異常不是敵人,而是系統健康狀態的信號。建立分層異常體系、採用結構化錯誤處理、配合監控告警,讓異常成為快速定位問題的利器,而非令人頭痛的 Bug 來源。

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