網頁

2020/9/15

Java 雙括弧初始化 double brace initialization

最近在專案中看到直接建立帶有元素的ArrayList物件的特殊寫法如下。

package abc.com;

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        List<String> list = new ArrayList<String>(){{
            add("a");
            add("b");
            add("c");
        }};
        
        System.out.println(list.toString()); // [a, b, c]
        
        System.out.println(list.getClass().getName()); // abc.com.Main$1

    }
    
}

這種寫法稱為雙括弧初始化(double brace initialization)。

new ArrayList<String>(){ { ... } }其實是建立一個繼承ArrayList匿名類別(anonymous class)(外括弧),並新增(覆寫)了初始化區塊(initialization block)(內括弧),然後在區塊內撰寫新增元素的語法。

double brace initialization語法雖然寫起來方便,但缺點是每用一次就代表建立並載入一個新的類別,對效能有不良影響;又匿名類別總是參照所屬的外層類別(enclosing class),因此double brace initialization建立的集合物件若持續被參照(例如長時間存在記憶體中),則外層類別物件將無法被垃圾回收(garbage collection),有記憶體洩漏(memory leak)的問題,所以不建議使用此寫法來初始化集合物件。 。

要建立即合物件時即初始化元素,可改用Arrays.asList()

List<String> list = Arrays.asList("a", "b", "c);

或用Java 9的List.of()

List<String> stringList = List.of("a", "b", "c");

或是傳統一點,先新增好空集合再新增元素。

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");


沒有留言:

張貼留言