本文深入剖析 Java 內部類四大類型(成員、靜態、局部、匿名)的語法、訪問規則、編譯產物與應用場景,並系統講解異常體系架構、處理流程、自定義異常設計、常見異常類別與最佳實踐原則。
Outer.Inner in = new Outer().new Inner();static 修飾,不依賴外部類實例。new Outer().field。Outer.StaticInner si = new Outer.StaticInner();private 修飾(編譯錯誤)。final/effectively final 區域變數(JDK8+ 隱含 final)。Outer$1Inner.class、Outer$2Inner.class 等。new SuperType() { ... } 或 new Interface() { ... }。Outer.class
Outer$Inner.class // 成員內部類
Outer$StaticInner.class // 靜態內部類
Outer$1Local.class // 局部內部類(方法 1)
Outer$2Local.class // 局部內部類(方法 2)
Outer$1.class // 匿名內部類(第 1 個)
public class InnerDemo {
private int outerField = 10;
static int staticField = 20;
// 成員內部類
class MemberInner { void show() { System.out.println(outerField); } }
// 靜態內部類
static class StaticInner {
static void staticMethod() { System.out.println(staticField); }
void instanceMethod() { System.out.println(new InnerDemo().outerField); }
}
// 局部內部類
void methodLocal() {
final int localFinal = 5;
class LocalInner { void show() { System.out.println(localFinal); } }
new LocalInner().show();
}
// 匿名內部類
Runnable task = new Runnable() {
@Override public void run() { System.out.println("Anonymous run"); }
};
}
Throwable
├── Error // 嚴重錯誤,程式無法處理(OOM、StackOverflow)
└── Exception // 可處理異常
├── RuntimeException // 非受檢異常(空指針、越界、算術、類轉型)
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ ├── ArithmeticException
│ └── ClassCastException
└── Checked Exceptions // 受檢異常,編譯強制處理
├── IOException
├── SQLException
├── ClassNotFoundException
└── ParseException
// 1. try-catch-finally
try { risky(); }
catch (IOException e) { handleIO(e); }
catch (SQLException e) { handleSQL(e); }
finally { cleanup(); } // 必執行,return/throw 前執行
// 2. try-finally(無 catch,異常向上拋)
try { risky(); } finally { cleanup(); }
// 3. try-catch(無 finally)
try { risky(); } catch (Exception e) { handle(e); }
finally 不執行四種情況:finally 內拋異常、線程死亡、System.exit()、CPU 關機。
子類異常在前,父類在後,否則編譯錯誤(不可達代碼)。
public void readFile(String path) throws IOException, ParseException {
// 方法內拋出或調用拋出受檢異常的方法
}
if (age < 0) throw new IllegalArgumentException("年齡不可為負");
throw e; // 重新拋出捕獲的異常(保留堆疊追蹤)
// 業務異常:繼承 RuntimeException,不可恢復,需修正代碼
public class BizException extends RuntimeException {
private final int code;
public BizException(int code, String msg) { super(msg); this.code = code; }
public int getCode() { return code; }
}
// 受檢異常:繼承 Exception,呼叫者可嘗試恢復
public class CheckedBizException extends Exception {
public CheckedBizException(String msg) { super(msg); }
public CheckedBizException(String msg, Throwable cause) { super(msg, cause); }
}
設計原則:異常類名以 Exception 結尾;提供無參、訊息、原因、代碼等多重建構子;保留堆疊追蹤(fillInStackTrace() 可覆寫控制)。
| 異常 | 類別 | 典型場景 |
|---|---|---|
| NullPointerException | Runtime | 未實例化調用方法/欄位 |
| ArrayIndexOutOfBoundsException | Runtime | 陣列索引 < 0 或 >= length |
| NumberFormatException | Runtime | 字串轉數字格式錯誤 |
| ClassNotFoundException | Checked | 反射載入類失敗 |
| IOException | Checked | 檔案/網路 I/O 錯誤 |
| SQLException | Checked | 資料庫操作失敗 |
catch (Exception e) 吞沒錯誤。cause 鏈。try-with-resources (JDK7+) 自動關閉 AutoCloseable 資源。log.error("msg", e) 完整堆疊,避免 e.printStackTrace()。@throws 說明拋出條件與含義。