類的 初始化順序【轉(zhuǎn)載】
class ClassA{































當執(zhí)行到ClassA a = new ClassB();時開始加載ClassB,這里因為ClassB繼承ClassA,所以加載ClassA,在加載ClassA的時候執(zhí)行輸出:ClassA's static.。
ClassA加載完后,加載ClassB,這時執(zhí)行結(jié)果為:ClassB's static.。兩個類都加載完后開始構(gòu)建對象。
在構(gòu)建ClassB對象時,得先構(gòu)建父類對象ClassA,所以執(zhí)行分別為:ClassA's constructor.
ClassB's constructor.那么這句話完了。
到a=new ClassB();時,由于ClassA,ClassB已經(jīng)被加載過,在內(nèi)存中。所以只是簡單的進行構(gòu)建對象。輸出:ClassA's constructor.
ClassB's constructor.
希望大家多多指教。
============================
類的初始化分為類加載后的初始化和類實例化后的初始化,當new一個類的時候,如果此類沒有被加載到vm中,vm會先加載此類,當加載完成后vm會立即執(zhí) 行此類中的所有的靜態(tài)初始化代碼。加載完成后,vm會為實例分配內(nèi)存,然后執(zhí)行實例初始化代碼,最后是執(zhí)行構(gòu)造方法返回新建對象的引用。
靜態(tài)初始化代碼是被static修飾的字段或靜態(tài)代碼段,實例初始化代碼是類中聲明并初始化并且沒有被static修飾的字段,還有就是在類中被大括號括起來的代碼段
===========================
關鍵是要把握幾點
1. 對象實例初始化之前要初始化類實例,它們對應字節(jié)碼的方法名分別是 cinit() 和init(),類的靜態(tài)塊編譯后會放在 cinit() 方法中,{} 括起來的非靜態(tài)塊會放到 init() 方法中。
2. 構(gòu)造子對象實例前必須構(gòu)造出父對象實例,當然在構(gòu)造子類實例前必須構(gòu)造父類實例。
就這么兩點,這里用了類實例和對象實例。區(qū)別是,比如有個類A,分別構(gòu)造了
A a1 = new A();
A a2 = new A();
A a3 = new A();
三個是對象實例,但是只要同一個類加載器加載的,那么
a1.getClass()和a2.getClass(),a3.getClass() 就是同一個實例,叫做它們的類實例。
這里只簡單的說了是由同一個類加載器加的,如果延展開來就會比較復雜。根據(jù)類加載器的委托機制和可見性原則還會有不同的情況。
柳德才
13691193654
18942949207
QQ:422157370
liudecai_zan@126.com
湖北-武漢-江夏-廟山
posted on 2009-03-31 17:26 liudecai_zan@126.com 閱讀(164) 評論(0) 編輯 收藏 所屬分類: 程序人生