Java雙括弧初始化
常用的初始化方式
Java中可以使用括弧進行初始化,並且分為靜態代碼塊和非靜態代碼塊。如下:
public class Test { public static int num = 0; String s = ; { s = abc; System.out.println(non static init); } static { num = 1; System.out.println(static init); } public void runTest(){ System.out.println(num); System.out.println(s); }}
運行Test類的runTest方法,輸出如下:
static init
non static init
1
abc
從輸出結果可以看出,有static修飾的靜態代碼塊在非靜態代碼塊之前執行。
另外,非靜態代碼塊與靜態代碼塊有個區別:
靜態代碼塊,在虛擬機器載入類的時候就會載入執行,而且只執行一次;
非靜態代碼塊,在建立對象的時候(即new一個對象的時候)執行,每次建立對象都會執行一次。
為了驗證以上區別,寫測試程式如下:
Test test1 = new Test();Test1.runTest();Test test2 = new Test();test2.runTest();
輸出結果如下:
static init
non static init
1
abc
non static init
1
abc
驗證確實靜態代碼塊只執行一次,非靜態代碼塊每次建立都執行。
初始化的形式
除了以上的代碼塊方式進行初始化,Java中還有一種初始化方式,即雙括弧初始化。形式如下:
Test test = new Test(){ { num = 2; s = aaa; } }; test.runTest();
這樣輸出結果為:
static init
non static init
2
aaa
這種初始化方式實際上是利用了匿名類的特性。外層的括弧其實是建立了一個匿名的內部類,而內層的括弧是匿名類的建構函式,所以可以直接插入初始化代碼。
如果我們在內部建構函式和括弧形式的建構函式中分別列印一條資訊,可以得到如下結果:
static init
non static init
inner constructor
brackets constructor
2
aaa
括弧中的代碼晚於內部建構函式執行。
有什麼利弊
儘管雙括弧初始化方式讓編程的可讀性變得簡單,但是因為要建立一個匿名的內部類,匿名內部類會持有外部類的引用,有造成記憶體泄露的風險。