讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議39:使用匿名類的構造函數 >

建議39:使用匿名類的構造函數

閱讀如下代碼,看看是否可以編譯:


public static void main(Stringargs){

List l1=new ArrayList();

List l2=new ArrayList(){};

List l3=new ArrayList(){{}};

System.out.println(l1.getClass()==l2.getClass());

System.out.println(l2.getClass()==l3.getClass());

System.out.println(l1.getClass()==l3.getClass());

}


注意ArrayList後面的不同點:l1變量後面什麼都沒有,l2後面有一對{},l3後面有2對嵌套的{},這段程序能不能編譯呢?若能編譯,那輸出是多少呢?

答案是能編譯,輸出的是3個false。l1很容易解釋,就是聲明了ArrayList的實例對象,那l2和l3代表的是什麼呢?

(1)l2=new ArrayList(){}

l2代表的是一個匿名類的聲明和賦值,它定義了一個繼承於ArrayList的匿名類,只是沒有任何的覆寫方法而已,其代碼類似於:


//定義一個繼承ArrayList的內部類

class Sub extends ArrayList{

}

//聲明和賦值

List l2=new Sub();


(2)l3=new ArrayList(){{}}

這個語句就有點怪了,還帶了兩對大括號,我們分開來解釋就會明白了,這也是一個匿名類的定義,它的代碼類似於:


//定義一個繼承ArrayList的內部類

class Sub extends ArrayList{

{

//初始化塊

}

}

//聲明和賦值

List l3=new Sub();


看到了吧,就是多了一個初始化塊而已,起到構造函數的功能。我們知道一個類肯定有一個構造函數,且構造函數的名稱和類名相同,那問題來了:匿名類的構造函數是什麼呢?它沒有名字呀!很顯然,初始化塊就是它的構造函數。當然,一個類中的構造函數塊可以是多個,也就是說可以出現如下代碼:


List l3=new ArrayList(){{}{}{}{}{}};


上面的代碼是正確無誤,沒有任何問題的。現在清楚了:匿名函數雖然沒有名字,但也是可以有構造函數的,它用構造函數塊來代替,那上面的3個輸出就很清楚了:雖然父類相同,但是類還是不同的。