class Test { int num = 8; static //靜態程式碼塊 { System.out.println("靜態程式碼"); } { //構造程式碼塊 System.out.println(num); } public Test(int num) // 構造方法 { this.num = num; } } class TestDemo { public static void main(String[] args) { Test t = new Test(3); System.out.println(t.num); } }
輸出結果:
靜態程式碼
8
3
Test t = new Test(3);這句話都幹了什麼
1、new用到Test.class,先找到Test.class檔案並載入到記憶體中 (若如上num在類中靜態初始化,則num的值初始化為8,則下文的預設初始化就沒了)
2、執行該類的靜態程式碼塊(靜態的成員隨類載入而執行)
3、在堆記憶體中開闢記憶體空間,分配記憶體地址,並在棧中建立變數p。
4、在堆記憶體中建立物件的特有屬性,並進行預設初始化。
5、對屬性進行顯示初始化(即用語句對變數進行的初始化,這裡指上句中的3)
6、對物件的構造程式碼段初始化。
7、對物件的對應建構函式初始化。
8、將記憶體地址賦給記憶體中的變數。
這也可以解釋為什麼靜態方法不能呼叫非靜態成員了
注意:靜態的成員是按語句順序進行執行的,若程式碼如下:
1 static 2 { 3 System.out.println("靜態程式碼"+num); 4 } 5 static int num = 8;
則會出現非法向上引用的錯誤