異常是程式運行時的「體檢報告」。熟練解讀堆疊追蹤、定位根因,是從「寫出代碼」到「交付產品」的關鍵能力。本文梳理六大高頻異常的成因、現場重現與修復策略。
成因:引用未初始化的物件、陣列元素為 null、資源載入失敗 (圖片路徑錯誤) 後直接調用方法。
典型現場:Image img = Image.createImage("/res/missing.png"); img.getWidth(); → createImage 回傳 null。
對策:
if (img==null) throw new IllegalStateException("資源缺失: /res/missing.png");Actor[] actors = new Actor[10]; for(int i=0;iObjects.requireNonNull() (Java 7+) 或註解 @NonNull 配合靜態分析。成因:類路徑缺失、包名與目錄結構不符、打包時遺漏依賴 JAR、ProGuard 混淆誤刪。
對策:
CLASSPATH / MANIFEST.MF Class-Path 包含所有運行時依賴。-keep class com.mygame.** { *; } 保留入口類與反射用類。成因:整數除零、Math.floorDiv 溢位。
對策:除法前斷言 if (divisor==0) throw new IllegalArgumentException("除數為零");,或使用 Math.divideExact (Java 8+) 自動拋出異常。
成因:索引 < 0 或 ≥ length;動態計算索引時邊界條件疏漏(如 i <= len 應為 i < len)。
對策:
for (int i=0, n=arr.length; i。 assert index >=0 && index < arr.length (開啟 -ea)。List 避免手動管理陣列擴容。成因:API 參數不符合約束(如 setVolume(-1)、g.setColor(300,0,0)、Thread.sleep(-100))。
對策:封裝參數校驗工具類 Preconditions.checkArgument(vol>=0 && vol<=100, "音量範圍 0-100");。
成因:反射調用非 public 成員、模組系統 (JPMS) 未導出包、簽名不一致導致存取失敗。
對策:field.setAccessible(true);模組化項目在 module-info.java 中 opens com.mygame to java.base。
throws 條款、前置條件、副作用說明是權威來源。