Java中的雙大括號初始化

什么是Java雙大括號初始化?

通常情況下,初始化Java集合并向其中添加幾個元素的步驟如下:

Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);

或者我們可以在靜態(tài)初始化塊中向作為靜態(tài)變量的集合添加元素:

private static final Set<Integer> set = new HashSet<>();
static {
    set.add(1);
    set.add(2);
    set.add(3);
}

從語法上來看,這樣的初始化方法雖然格式清晰明了,但語法上略顯冗余。事實上,Java允許一種精簡的雙大括號初始化方法:

Set<Integer> set = new HashSet<Integer>() {{
    add(1);
    add(2);
    add(3);
}};

或是在接收集合作為輸入的函數(shù)中直接初始化:

someFunction(new HashSet<Integer>() {{
    add(1);
    add(2);
    add(3); 
}}
);

語法解讀

事實上,如下雙大括號初始化Set的代碼

Set<Integer> set = new HashSet<Integer>() {{
    add(1);
    add(2);
    add(3);
}};

是以下這段代碼的改寫:

Set<Integer> set = new HashSet<Integer>() {
    {
        add(1);
        add(2);
        add(3);
    }
};

改寫之后的代碼就非常容易理解了。顯然這是在HashSet的構(gòu)造器中寫了一個匿名內(nèi)部類,這個匿名內(nèi)部類含有一個實例初始化塊,初始化塊的內(nèi)容是三個add()函數(shù),向被初始化的this指向的HashSet中添加了三個元素。

效率問題和產(chǎn)生的.class文件結(jié)構(gòu)

利用雙大括號初始化集合從效率上來說可能不如標(biāo)準(zhǔn)的集合初始化步驟。原因在于使用雙大括號初始化會導(dǎo)致內(nèi)部類文件的產(chǎn)生,而這個過程就會影響代碼的執(zhí)行效率。

例如如下代碼:

// Double brace initialization
class Test1 {
    public static void main(String[] args) {
        long st = System.currentTimeMillis();

    Set<Integer> set0 = new HashSet<Integer>() {{
        add(1);
        add(2);
    }};

    Set<Integer> set1 = new HashSet<Integer>() {{
        add(1);
        add(2);
    }};
    
    /* snip */

    Set<Integer> set999 = new HashSet<Integer>() {{
        add(1);
        add(2);
    }};

      System.out.println(System.currentTimeMillis() - st);
  }
}
// Normal initialization
class Test2 {
    public static void main(String[] s) {
        long st = System.currentTimeMillis();

        Set<Integer> set0 = new HashSet<Integer>();
        set0.add(1);
        set0.add(2);

        Set<Integer> set1 = new HashSet<Integer>();
        set1.add(1);
        set1.add(2);
        
        /* snip */

        Set<Integer> set999 = new HashSet<Integer>();
        set999.add(1);
        set999.add(2);  
        System.out.println(System.currentTimeMillis() - st);
  }
}

javac命令compile第一段代碼會產(chǎn)生1000個.class文件,如下所示:

Test1$1.class
Test1$2.class
...
Test1$1000.class

同時從程序輸出的運行時間來看, 雙大括號初始化也顯著慢于普通初始化的代碼。差值大約在100ms左右。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,662評論 18 399
  • (一)Java部分 1、列舉出JAVA中6個比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨云閱讀 7,256評論 0 62
  • 公元二零一六年八月十八號,你被天使安排來到了我們的身邊,當(dāng)時你帶著3.2kg的小身板,伴著哭聲,一絲不掛! ...
    揮霍5211閱讀 395評論 2 3
  • 攝影師才才閱讀 319評論 1 0
  • 兩個星期的理財訓(xùn)練營即將結(jié)束,我心中感慨良多。首先感謝長投網(wǎng)給了我們一個這樣的平臺,其次感謝班班和學(xué)姐們的悉悉...
    胖朱瘦瓜閱讀 297評論 1 2

友情鏈接更多精彩內(nèi)容