資源描述:
《分析Java類(lèi)加載全過(guò)程.docx》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫(kù)。
1、分析Java類(lèi)加載全過(guò)程2012-11-0610:19OSCHINA?字號(hào):T?
2、?T一個(gè)Java文件從被加載到被卸載這個(gè)生命過(guò)程,總共要經(jīng)歷4個(gè)階段,那么是哪4個(gè)階段呢?下面作者將詳細(xì)的給網(wǎng)友解答……AD:WOT2015互聯(lián)網(wǎng)運(yùn)維與開(kāi)發(fā)者大會(huì)熱銷(xiāo)搶票今天去涉獵了一下類(lèi)的加載的過(guò)程,現(xiàn)在也總結(jié)一下:一個(gè)java文件從被加載到被卸載這個(gè)生命過(guò)程,總共要經(jīng)歷4個(gè)階段:加載->鏈接(驗(yàn)證+準(zhǔn)備+解析)->初始化(使用前的準(zhǔn)備)->使用->卸載其中加載(除了自定義加載)+鏈接的過(guò)程是完全由jvm負(fù)責(zé)的,什么時(shí)候要對(duì)類(lèi)進(jìn)行初始化工作(加載+鏈接在此之前已經(jīng)完成了),jvm有嚴(yán)格的規(guī)定(四種情況)
3、:1.遇到new,getstatic,putstatic,invokestatic這4條字節(jié)碼指令時(shí),加入類(lèi)還沒(méi)進(jìn)行初始化,則馬上對(duì)其進(jìn)行初始化工作。其實(shí)就是3種情況:用new實(shí)例化一個(gè)類(lèi)時(shí)、讀取或者設(shè)置類(lèi)的靜態(tài)字段時(shí)(不包括被final修飾的靜態(tài)字段,因?yàn)樗麄円呀?jīng)被塞進(jìn)常量池了)、以及執(zhí)行靜態(tài)方法的時(shí)候。2.使用java.lang.reflect.*的方法對(duì)類(lèi)進(jìn)行反射調(diào)用的時(shí)候,如果類(lèi)還沒(méi)有進(jìn)行過(guò)初始化,馬上對(duì)其進(jìn)行。3.初始化一個(gè)類(lèi)的時(shí)候,如果他的父親還沒(méi)有被初始化,則先去初始化其父親。4.當(dāng)jvm啟動(dòng)時(shí),用戶需要指定一個(gè)要執(zhí)行的主類(lèi)(包含staticvoidmain(String
4、[]args)的那個(gè)類(lèi)),則jvm會(huì)先去初始化這個(gè)類(lèi)。以上4種預(yù)處理稱(chēng)為對(duì)一個(gè)類(lèi)進(jìn)行主動(dòng)的引用,其余的其他情況,稱(chēng)為被動(dòng)引用,都不會(huì)觸發(fā)類(lèi)的初始化。下面也舉了些被動(dòng)引用的例子:1./**?2.?*?被動(dòng)引用情景1?3.?*?通過(guò)子類(lèi)引用父類(lèi)的靜態(tài)字段,不會(huì)導(dǎo)致子類(lèi)的初始化?4.?*?@author?volador?5.?*?6.?*/?7.class?SuperClass{?8.????static{?9.????????System.out.println("super?class?init.");?10.????}?11.????public?static?int?value=12
5、3;?12.}?13.?14.class?SubClass?extends?SuperClass{?15.????static{?16.????????System.out.println("sub?class?init.");?17.????}?18.}?1.?2.public?class?test{?3.????public?static?void?main(String[]args){?4.????????System.out.println(SubClass.value);?5.????}?6.?????7.}?輸出結(jié)果是:superclassinit。1./**?2.?*?被
6、動(dòng)引用情景2?3.?*?通過(guò)數(shù)組引用來(lái)引用類(lèi),不會(huì)觸發(fā)此類(lèi)的初始化?4.?*?@author?volador?5.?*?6.?*/?7.public?class?test{?8.????public?static?void?main(String[]?args){?9.????????SuperClass?s_list=new?SuperClass[10];?10.????}?11.}?輸出結(jié)果:沒(méi)輸出1./**?2.?*?被動(dòng)引用情景3?3.?*?常量在編譯階段會(huì)被存入調(diào)用類(lèi)的常量池中,本質(zhì)上并沒(méi)有引用到定義常量類(lèi)類(lèi),所以自然不會(huì)觸發(fā)定義常量的類(lèi)的初始化?4.?*?@author?r
7、oot?5.?*?6.?*/?7.class?ConstClass{?8.????static{?9.????????System.out.println("ConstClass?init.");?10.????}?11.????public?final?static?String?value="hello";?12.}?13.?14.public?class?test{?15.????public?static?void?main(String[]?args){?16.????????System.out.println(ConstClass.value);?17.????}?18.
8、}?輸出結(jié)果:hello(tip:在編譯的時(shí)候,ConstClass.value已經(jīng)被轉(zhuǎn)變成hello常量放進(jìn)test類(lèi)的常量池里面了)以上是針對(duì)類(lèi)的初始化,接口也要初始化,接口的初始化跟類(lèi)的初始化有點(diǎn)不同:上面的代碼都是用static{}來(lái)輸出初始化信息的,接口沒(méi)法做到,但接口初始化的時(shí)候編譯器仍然會(huì)給接口生成一個(gè)()的類(lèi)構(gòu)造器,用來(lái)初始化接口中的成員變量,這點(diǎn)在類(lèi)的初始化上也有做到。真正不同的地方在于第三點(diǎn),類(lèi)的初始化執(zhí)行之