關於java的初始化順序

jacobzheng發表於2004-12-07
最近在研究java基礎,對於java初始化的順序一直沒有搞清楚,找了很多資料和文章也還是依然費解。於是決定,自己研究,終於在一個小風嗖嗖的晚上搞清楚了order of initialization,現在分享給大家!
第一步:find class:這個時候jvm會找尋.class檔案,.class像個產品的磨具一樣,是用來產生object產品的而不是.class本身。
第二步:create object class:往往很少有人注意到這點,這也是一個oject也同樣佔用記憶體資源可是和傳統意義上的object不一樣,他是一個類似於磨具的東西,可和object一樣佔用空間。在第二步的時候我們會看到static field的東西得到了初始化,所以說static 的東西是屬於類物件而不是屬於物件的。當.class第一次被匯入的時候,被static修飾過的東西也隨之allocate。所以我們能夠有Class2.classField/Class2.classMethod的寫法,這些東西是隻佔用一塊記憶體空間的和new instance 沒有任何關係。對於沒有被static修飾過的field就屬於instance field了,這個時候obj.classField/obj.classMethod的寫法就產生了,他們和new instance 由某種惟妙惟肖的關係。
第三步:Definition initializaiont:這個時候程式會做一些定義初始化的動作,比如class類裡面的field的初始化。
最後一步:Construction initialization:這個地球人都知道了,我就不說了。

下面是一個例子,看看是否和你的想象一樣。
class Cup
{
Cup(int marker)
{
System.out.println("Cup(" + marker + ")");
}
void f(int marker)
{
System.out.println("f(" + marker + ")");
}
}
class Cups
{
static Cup c1=new Cup(1);
Cup c3=new Cup(3);
static Cup c2= new Cup(2);
Cups()
{
System.out.println("Cups()");
}
Cup c4=new Cup(4);
}
public class ExplicitStatic
{
Cups c=new Cups();
{
System.out.println("Hello");
}
public static void main(String[] args)
{
System.out.println("Inside main()");
Cups.c1.f(99);
ExplicitStatic x=new ExplicitStatic();
}
static Cups x = new Cups();
}

大家可以手動執行一下這個程式,考慮一下結果是什麼,然後參照下面的答案對照一下,看看是否正確:
Cup(1)
Cup(2)
Cup(3)
Cup(4)
Cups()
Inside main()
f(99)
Cup(3)
Cup(4)
Cups()
Hello
因為Static是屬於類物件的所以,只初始化一次。也正是因為Static是屬於類物件的所以,先處理被Static修飾過的東西。

Plus:
class field:共用一塊記憶體
class method:共用一塊記憶體
instance field:隨著每個instance各有一塊記憶體
instance method:共用一塊記憶體(_! why?)
JVM為了節省空間,所以
instance1.instanceMethod();
instance2.instanceMethod();
編譯器會吧instance1和instance2作為instanceMethod()的一個隱藏的引數傳入方法內(當然我們是看不到了)。這個東東就是我們常常說的this。用這種方法來區分是哪一個instance來呼叫方法,哎Gosling就是聰明。

相關文章