Java中雙括號初始化是個什么操作
最近在閱讀Mybatis源碼的時候,看到了一種原來很少見到的語法:
public class RichType {
...
private List richList = new ArrayList() {
{
add("bar");
}
};
}
查了一下資料,補足了自己的一個知識盲區,嘻嘻。
一. 什么是Java雙大括號初始化?
通常情況下,初始化Java集合并向其中添加幾個元素的步驟如下:
public class RichType {
...
private List richList;
public RichType(){
richList = new ArrayList();
richList.add("bar");
}
}
或者我們可以在靜態初始化塊中向作為靜態變量的集合添加元素:
public class RichType {
...
private static List richList = new ArrayList();
static{
richList.add("bar");
}
}
從語法上來看,這樣的初始化方法雖然格式清晰明了,但語法上略顯冗余。事實上,Java允許一種精簡的雙大括號初始化方法:
List richList = new ArrayList() {
{
add("bar");
}
};
二. 語法解讀
實際上上述語法可以拆為兩個部分,第一部分是創建了一個繼承于ArrayList的匿名內部類:
List richList = new ArrayList() {
};
第二部分,是在匿名內部類中指定了一個初始化塊,并在初始化塊中調用對象本身的add方法添加元素:
List richList = new ArrayList() {
{
add("bar");
}
};
這里需要回顧一下類的初始化方式,在Java中一個類和實例的初始化可以有三種方式:
- 靜態初始化塊:靜態初始化塊只在類加載時執行一次,同時靜態初始化塊只能給靜態變量賦值,不能初始化普通的成員變量。
- 初始化塊:非靜態初始化塊在每次初始化實例對象的時候都執行一次,可以給任意變量賦值。
- 構造方法:在每次初始化實例對象時調用。
初始化塊的順序
- 在加載類時執行一次靜態初始化塊(之后不再調用)。
- 在每次初始化實例對象時:先執行非靜態初始化塊,
- 再執行構造方法。
三. 效率問題和產生的.class文件結構
利用雙大括號初始化集合從效率上來說可能不如標準的集合初始化步驟。原因在于使用雙大括號初始化會導致內部類文件的產生,而這個新的.class文件產生就會導致需要再次進行類加載的操作,會影響最終效率。

浙公網安備 33010602011771號