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

Java 雙大括號初始化靜態常量技巧 (Double Brace Initialization)

     編輯:Java 相關知識

Java 雙大括號初始化:匿名內部類實例初始化器

標題技巧:使用匿名內部類搭配實例初始化器(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");
    // ...
}};

原理解析

  1. 外層 `new HashMap<...>()` 建立匿名子類實例。
  2. 內層 `{ ... }` 是該匿名子類的實例初始化器,在建構子執行前自動運行。
  3. 初始化器中 `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) 標記為代碼異味

現代替代方案 (Java 9+)

// 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),語意明確、不可變、無額外類別、效能最佳。

適用場景

  • 測試代碼、一次性腳本、原型驗證。
  • 需在初始化邏輯中使用外部變數且無記憶體洩漏風險的短生命週期物件。
  • 舊版本 Java (≤8) 且不想引入 Guava `ImmutableMap` 等第三方庫時的折衷方案。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved