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

Java 雙大括號初始化技巧:匿名內部類與實例初始化塊的巧妙結合

     編輯:Java 相關知識

前言

Java 集合框架缺乏字面量語法,構建常量集合往往需要「聲明變量 → new 實例 → 多次 add → 傳參」四步。雙大括號初始化 利用匿名內部類 + 實例初始化塊,將聲明與初始化合為一句,顯著提升可讀性。

語法原理解析

new HashSet<String>() {{
    add("XZ13s");
    add("AB21/X");
    add("YYLEX");
    add("AR2D");
}};
結構本質執行時機
外層 {}匿名內部類(繼承 HashSet)類加載/實例化時
內層 {{}}實例初始化塊構造器之前,每次 new 都執行

等價於:

new HashSet<String>() {
    {   // 實例初始化塊
        add("XZ13s"); ...
    }
};

核心優勢

  1. 一行式聲明初始化:可直接作為方法參數傳遞。
  2. 適用於所有非 final 類:集合、GUI 組件、Builder 模式等。
  3. Map 初始化極其優雅:
Map<String, Set<String>> baselineMap = new HashMap<>();
baselineMap.put(type, new HashSet<String>() {{ add(schema); }});
// 或合併現有集合
baselineMap.put(type, new HashSet<String>(baselineMap.get(type)) {{ add(schema); }});

GUI 組件構建示例

add(new JPanel() {{
    setLayout(new BorderLayout());
    setBorder(BorderFactory.createTitledBorder("設定"));
    add(new JLabel("名稱:"), BorderLayout.WEST);
    add(new JTextField(20), BorderLayout.CENTER);
}});

⚠️ 關鍵限制與風險

風險說明緩解方案
持有外部類引用匿名內部類隱式持有 OuterClass.this靜態上下文使用;或改用靜態工廠方法
序列化失敗外部類未實現 Serializable 會導致 NotSerializableException確保外部類可序列化;或改用普通初始化
類爆炸每次調用生成一個匿名類 .class 文件僅用於常量/啟動期初始化,避免高頻調用熱點
final 類不可用String、Integer 等 final 類無法繼承改用 List.of()、Set.of()、Map.of()(Java 9+)
equals/hashCode 異常匿名子類可能破壞父類 equals 契約不將雙大括號實例作為 Map 鍵/Set 元素

現代替代方案(Java 9+ 推薦)

// 不可變集合字面量語法
List.of("a", "b", "c");
Set.of("x", "y");
Map.of("k1", "v1", "k2", "v2");
Map.ofEntries(entry("k1","v1"), entry("k2","v2"));

// 可變集合單表達式
new ArrayList<>(List.of("a", "b", "c"));
new HashSet<>(Set.of("x", "y"));
new HashMap<>(Map.of("k1", "v1"));

結論:Java 9+ 項目優先使用標準工廠方法;維舊項目或需可變集合單表達式時,雙大括號仍是實用技巧,但務必了解其副作用。

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