Java中雙大括號(hào)初始化的理解與使用
偶然機(jī)會(huì)看到一種對(duì)象初始的方式:
// 新建一個(gè)列表,并賦值 "Harry","Tony","Tom" ArrayList<String> friends = new ArrayList<String>() {{ add("Harry"); add("Tony"); add("Tom"); }};
當(dāng)然,對(duì)Map集合也用同種初始化方式:
// 新建一個(gè)Map,并賦值 Map<String, Object> cat = new HashMap<String, Object>() {{ put("name", "Tom"); put("age", 10); }};
這里利用了內(nèi)部類語法,這種方式比先new出對(duì)象然后再進(jìn)行依次add要方便、簡(jiǎn)潔許多。該方法稱之為“雙括號(hào)初始化”(double brace initialization)。
對(duì)該方法的理解
以ArrayList的初始化為例,第一層花括號(hào),首先對(duì)定義了一個(gè)繼承自ArrayList的匿名內(nèi)部類
ArrayList<String> friends = new ArrayList<String>() { // 這里什么操作都沒有,全部繼承自父類(ArrayList) };
第二層則是一個(gè)自定義的對(duì)象構(gòu)造塊(稱之為 非靜態(tài)初始化塊)
new ArrayList<String>() { // 這里什么操作都沒有,全部繼承自父類(ArrayList) };
我們通過new得到ArrayList的子類的實(shí)例化,然后上轉(zhuǎn)型為ArrayList的引用
ArrayList<String> friends = new ArrayList<String>() {{}};
- 我們得到的 friends 實(shí)際上是ArrayList的子類的引用,但在功能上沒有任何改變
- 相比于常規(guī)標(biāo)準(zhǔn)方式進(jìn)行初始化要簡(jiǎn)潔許多(但代碼可讀性相對(duì)會(huì)差)
效率問題
利用雙大括號(hào)初始化集合從效率上來說可能不如標(biāo)準(zhǔn)的集合初始化步驟。原因在于使用雙大括號(hào)初始化會(huì)導(dǎo)致內(nèi)部類文件的產(chǎn)生,而這個(gè)過程就會(huì)影響代碼的執(zhí)行效率。
首先查看不同初始化方式生成的.class文件
例如以下代碼:
public class Test1 { public static void main(String[] args) { System.out.println(System.currentTimeMillis()); ArrayList<String> list1 = new ArrayList<String>() {{ add("Harry"); add("Tony"); add("Tom"); add("Jerry"); }}; ArrayList<String> list2 = new ArrayList<String>() {{ add("Harry"); add("Tony"); add("Tom"); add("Jerry"); }}; ArrayList<String> list3 = new ArrayList<String>() {{ add("Harry"); add("Tony"); add("Tom"); add("Jerry"); }}; ArrayList<String> list4 = new ArrayList<String>() {{ add("Harry"); add("Tony"); add("Tom"); add("Jerry"); }}; ArrayList<String> list5 = new ArrayList<String>() {{ add("Harry"); add("Tony"); add("Tom"); add("Jerry"); }}; …… …snip… …… ArrayList<String> list1000 = new ArrayList<String>() {{ add("Harry"); add("Tony"); add("Tom"); add("Jerry"); }}; System.out.println(System.currentTimeMillis()); } }
Test1編譯后生成的.class列表為:
Test1$1.class
Test1$2.class
Test1$3.class
Test1$4.class
Test1$5.class
……
…snip…
……
Test1$1000.class
Test1.class
生成了 1001個(gè).class文件
public class Test2 { public static void main(String[] args) { System.out.println(System.currentTimeMillis()); ArrayList<String> list1 = new ArrayList<>(); list1.add("Harry"); list1.add("Tony"); list1.add("Tom"); list1.add("Jerry"); ArrayList<String> list2 = new ArrayList<>(); list2.add("Harry"); list2.add("Tony"); list2.add("Tom"); list2.add("Jerry"); ArrayList<String> list3 = new ArrayList<>(); list3.add("Harry"); list3.add("Tony"); list3.add("Tom"); list3.add("Jerry"); ArrayList<String> list4 = new ArrayList<>(); list4.add("Harry"); list4.add("Tony"); list4.add("Tom"); list4.add("Jerry"); ArrayList<String> list5 = new ArrayList<>(); list5.add("Harry"); list5.add("Tony"); list5.add("Tom"); list5.add("Jerry"); …… …snip… …… ArrayList<String> list1000 = new ArrayList<>(); list1000.add("Harry"); list1000.add("Tony"); list1000.add("Tom"); list1000.add("Jerry"); System.out.println(System.currentTimeMillis()); } }
Test2編譯后生成的.class列表為:
Test2.class
只生成了1個(gè).class文件
運(yùn)行時(shí)間
第一段代碼Test1運(yùn)行結(jié)果:
1508379452224
1508379452784
運(yùn)行時(shí)間為:560毫秒
第二段代碼Test2運(yùn)行結(jié)果:
1508379671505
1508379671507
運(yùn)行時(shí)間為:2毫秒
雖然說這個(gè)時(shí)間差距會(huì)根據(jù)電腦性能以及運(yùn)行狀態(tài)有所變化,但也能說明雙大括號(hào)初始化方法要比常規(guī)方法用時(shí)長(zhǎng)
綜上,(測(cè)試初始化數(shù)據(jù)較少(list未達(dá)到自增臨界點(diǎn))的情況下)雙大括號(hào)初始化方法要比常規(guī)方法效率低:
1. 雙大括號(hào)初始化方法生成的.class文件要比常規(guī)方法多
2. 雙大括號(hào)初始化方法運(yùn)行時(shí)間要比常規(guī)方法長(zhǎng)
總結(jié)
到此這篇關(guān)于Java中雙大括號(hào)初始化的理解與使用的文章就介紹到這了,更多相關(guān)Java雙大括號(hào)初始化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea啟動(dòng)spring項(xiàng)目中文亂碼的解決方法
本文主要介紹了idea啟動(dòng)spring項(xiàng)目中文亂碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01解決Springboot項(xiàng)目中很多頁面出現(xiàn)Whitelabel Error Page(404)的問題
最近在接手的前后端項(xiàng)目中發(fā)現(xiàn)其默認(rèn)路徑不是主機(jī)+端口(如:http://localhost:3453/)的形式,很多頁面的訪問是加了一個(gè)層級(jí),只要訪問頁面就會(huì)出現(xiàn)Whitelabel Error Page(404),所以本文給大家提供了解決方案,需要的朋友可以參考下2024-02-02mybatis自動(dòng)填充時(shí)間字段示例代碼
這篇文章主要給大家介紹了關(guān)于mybatis自動(dòng)填充時(shí)間字段的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01Spring security BCryptPasswordEncoder密碼驗(yàn)證原理詳解
這篇文章主要介紹了Spring security BCryptPasswordEncoder密碼驗(yàn)證原理詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03java實(shí)現(xiàn)多文件上傳至本地服務(wù)器功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)多文件上傳至本地服務(wù)器功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01