標題技巧:使用匿名內部類搭配實例初始化器(Instance Initializer),在宣告集合/Map 時直接填入資料,省去靜態區塊或建構子呼叫。
public static final Map DATA = new HashMap<>();
static {
DATA.put("a", "A");
DATA.put("b", "B");
// ...
}
public static final Map DATA = new HashMap() {{
put("a", "A");
put("b", "B");
// ...
}};
new HashMap<...>()` 建立匿名子類實例。{ ... }` 是該匿名子類的實例初始化器,在建構子執行前自動運行。this` 指向該匿名子類實例,可直接呼叫 `put()` 等方法。等價於:
public static final Map DATA = new HashMap() {
{ // 實例初始化器
put("a", "A");
put("b", "B");
}
};
| 優點 | 缺點 |
|---|---|
| 語法緊湊、宣告與初始化合一 | 產生額外匿名類別 Class 檔案 (如 `Main$1.class`),增加 Metaspace 佔用 |
| 可直接存取外部 final/效果上 final 變數 | 持有外部類 `this` 參考,若作為長生命週期常量可能造成記憶體洩漏 (外部類無法 GC) |
| 支援任意複雜初始化邏輯 (迴圈、條件) | equals()/`hashCode()` 行為可能與預期不同 (繼承自父類,但類型不同) |
| 序列化時需注意 `serialVersionUID` | 某些靜態分析工具 (SonarQube) 標記為代碼異味 |
// Map.of / Map.ofEntries (不可變)
public static final Map DATA = Map.of(
"a", "A",
"b", "B"
);
// 或可變 Map
public static final Map DATA = new HashMap<>(Map.of(
"a", "A",
"b", "B"
));
// List.of / Set.of
public static final List ITEMS = List.of("A", "B", "C");
推薦:優先使用 `Map.of`/`List.of`/`Set.of` (Java 9+) 或 `Collections.unmodifiableMap` (Java 8),語意明確、不可變、無額外類別、效能最佳。