類(lèi)加載機(jī)制

類(lèi)的加載階段

類(lèi)的整個(gè)生存周期包括:加載平夜、驗(yàn)證腰鬼、準(zhǔn)備藐握、解析、初始化垃喊。

加載

加載時(shí)類(lèi)的加載階段的開(kāi)始,包括三步

1)ClassLoader以全限定名形式從class文件中讀取二進(jìn)制數(shù)據(jù)流

2)將字節(jié)碼轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)

3)創(chuàng)建class文件對(duì)象袜炕,存放在堆中本谜,作為程序訪問(wèn)方法區(qū)中字節(jié)碼的入口

校驗(yàn)

驗(yàn)證輸入的字節(jié)流是否符合java虛擬機(jī)規(guī)范以及java語(yǔ)義,要保證到達(dá)解析階段時(shí)的正確性偎窘,包括:文件格式校驗(yàn)乌助、元數(shù)據(jù)校驗(yàn)溜在、字節(jié)碼校驗(yàn)、符號(hào)引用校驗(yàn)

文件格式校驗(yàn)

例如有魔術(shù)校驗(yàn)他托、class文件版本是否被當(dāng)前java虛擬機(jī)支持掖肋、常量池中的常量是否是支持的類(lèi)型。文件格式校驗(yàn)主要是保證輸入的字節(jié)流能被正確的解析并存儲(chǔ)到方法區(qū)中赏参,經(jīng)過(guò)了這個(gè)階段的驗(yàn)證志笼,字節(jié)流才會(huì)被存儲(chǔ)到方法區(qū)中。因此把篓,后續(xù)的三個(gè)校驗(yàn)都是對(duì)方法區(qū)中數(shù)據(jù)進(jìn)行校驗(yàn)的纫溃。

元數(shù)據(jù)校驗(yàn)

主要是進(jìn)行語(yǔ)義校驗(yàn),例如

1)是否有父類(lèi)韧掩,父類(lèi)是否是final類(lèi)型

2)如果當(dāng)前類(lèi)不是抽象類(lèi)紊浩,那么是否實(shí)現(xiàn)了父類(lèi)或接口需要實(shí)現(xiàn)的所有方法

3)類(lèi)中的字段、方法是否與父類(lèi)發(fā)生沖突(final類(lèi)型不允許重寫(xiě)疗锐;重寫(xiě)的方法是否符合規(guī)范等)

準(zhǔn)備

準(zhǔn)備階段是為類(lèi)的靜態(tài)成員變量賦予初始值的一個(gè)過(guò)程坊谁,對(duì)應(yīng)內(nèi)存將在方法區(qū)中進(jìn)行分配。

例如 public static int value = 1;

那么準(zhǔn)備階段value會(huì)被賦值為0滑臊,賦值為1的操作是在初始化階段完成的口芍。還有一種情況:

public static final int value = 1;此時(shí)在準(zhǔn)備階段value就會(huì)被賦值為1.

解析

解析就是將常量池中符號(hào)引用替換為直接引用的過(guò)程。解析主要針對(duì):類(lèi)简珠、接口阶界、字段、類(lèi)方法聋庵、接口方法膘融。



此時(shí)類(lèi)方法解析的只是一部分在編譯期確定,運(yùn)行時(shí)已知的方法祭玉,包括構(gòu)造方法氧映、final修飾的方法、私有方法脱货、靜態(tài)方法岛都、類(lèi)方法。但是像重寫(xiě)的方法是無(wú)法做到這一點(diǎn)的振峻,重寫(xiě)的方法需要在運(yùn)行時(shí)做動(dòng)態(tài)解析臼疫,舉個(gè)例子:

輸出結(jié)果很簡(jiǎn)單。分析下main()方法的執(zhí)行過(guò)程:

java虛擬機(jī)中將Human man和Human woman稱(chēng)為靜態(tài)變量扣孟,右側(cè)的對(duì)象稱(chēng)為實(shí)際用例烫堤。如果是方法重載,例如a(Human human),a(Man man),a(Woman man),此時(shí)如果執(zhí)行a方法傳入man或者h(yuǎn)uman鸽斟,則都將調(diào)用a(Human human)方法拔创,而不會(huì)調(diào)用另外兩個(gè),這是因?yàn)橹剌d方法確認(rèn)時(shí)是根據(jù)左側(cè)的靜態(tài)變量確定調(diào)用哪個(gè)方法的富蓄。但是對(duì)于本例的重寫(xiě)方法:

1:在操作數(shù)棧中壓入Human man = new Man()對(duì)應(yīng)的指令(其實(shí)是三個(gè)剩燥,申請(qǐng)堆內(nèi)存、實(shí)例化立倍、賦值)

2:同1灭红,創(chuàng)建Human man = new Woman()

3:從操作數(shù)棧確定靜態(tài)變量man對(duì)應(yīng)的實(shí)際用例,然后執(zhí)行實(shí)際用例的sayHello()方法帐萎,再將執(zhí)行sayHello()對(duì)應(yīng)指令壓入棧

4:同3步驟比伏。

這就是多態(tài)在運(yùn)行時(shí)的動(dòng)態(tài)鏈接過(guò)程,此過(guò)程無(wú)法在類(lèi)的解析階段進(jìn)行疆导,只能在運(yùn)行時(shí)確定赁项。

以上是java虛擬機(jī)一書(shū)中的解釋。其實(shí)解析階段就是對(duì)類(lèi)或接口中的信息的解析澈段,解析后從類(lèi)或接口中獲取字段或方法的直接引用悠菜,然后進(jìn)行權(quán)限校驗(yàn)

初始化

初始化發(fā)生在加載、驗(yàn)證败富、準(zhǔn)備悔醋、解析之后。在準(zhǔn)備階段會(huì)完成靜態(tài)成員變量的賦初始值操作兽叮,而初始化階段則是完成其賦值和靜態(tài)代碼塊的執(zhí)行芬骄,執(zhí)行發(fā)生在構(gòu)造器函數(shù)(并非構(gòu)造方法)中。

類(lèi)構(gòu)造器

1)類(lèi)構(gòu)造器由編譯器生成鹦聪,其中包含靜態(tài)成員變量的賦值和靜態(tài)代碼塊的執(zhí)行账阻。順序和其在源文件中出現(xiàn)的順序一致,靜態(tài)代碼塊可以訪問(wèn)和賦值出現(xiàn)在其之前的靜態(tài)成員變量泽本,對(duì)之后的靜態(tài)成員變量只能賦值不能訪問(wèn)

2)虛擬機(jī)會(huì)保證父類(lèi)的類(lèi)構(gòu)造器一定發(fā)生在子類(lèi)構(gòu)造器開(kāi)始執(zhí)行之前執(zhí)行完畢

3)類(lèi)構(gòu)造器對(duì)于類(lèi)或接口并不是必須的淘太,如果類(lèi)中沒(méi)有靜態(tài)成員變量或靜態(tài)語(yǔ)句塊兒,接口中沒(méi)有成員變量规丽,則在類(lèi)和接口中并不會(huì)生成類(lèi)構(gòu)造器

4)接口的類(lèi)構(gòu)造器執(zhí)行之前并不要求父接口構(gòu)造器先執(zhí)行蒲牧。只有當(dāng)父接口中的成員變量被訪問(wèn)時(shí),父接口才會(huì)被初始化赌莺,即使接口的實(shí)現(xiàn)類(lèi)在初始化時(shí)也不會(huì)執(zhí)行父接口的類(lèi)構(gòu)造器的執(zhí)行

5)虛擬機(jī)會(huì)保證類(lèi)的類(lèi)構(gòu)造器方法在執(zhí)行時(shí)冰抢,多線程情況下的同步。也就是說(shuō)只有一個(gè)線程可以完成類(lèi)構(gòu)造器的執(zhí)行艘狭,其他線程都要阻塞晒屎,直到構(gòu)造器方法執(zhí)行完成喘蟆。因此在構(gòu)造器方法中不能執(zhí)行耗時(shí)操作,即靜態(tài)代碼塊的耗時(shí)操作

觸發(fā)初始化只有四個(gè)條件:

1)new 創(chuàng)建對(duì)象鼓鲁;訪問(wèn)類(lèi)的靜態(tài)成員變量、訪問(wèn)類(lèi)的靜態(tài)方法

2)以全限定名形式通過(guò)反射加載類(lèi)

3)加載類(lèi)時(shí)港谊,如果其父類(lèi)未初始化骇吭,那么先進(jìn)行父類(lèi)的初始化(繼承的接口不符合此邏輯。接口是只有在訪問(wèn)到接口中成員變量時(shí)才會(huì)去加載歧寺,并不會(huì)隨著實(shí)現(xiàn)類(lèi)而加載)

4)application啟動(dòng)時(shí)燥狰,主類(lèi)要進(jìn)行初始化,就是包含main()方法的類(lèi)斜筐。對(duì)于Android來(lái)說(shuō)就是ActivityThread

說(shuō)兩種容易混淆的初始化場(chǎng)景:

靜態(tài)成員變量的調(diào)用

上面的執(zhí)行代碼只會(huì)輸出SuperClass init!龙致,這是因?yàn)閖ava虛擬機(jī)規(guī)定,對(duì)于靜態(tài)成員變量顷链,只會(huì)初始化直接定義它的類(lèi)目代,因此只會(huì)輸出SuperClass init!

常量的訪問(wèn)


執(zhí)行結(jié)果并沒(méi)有輸出ConstClass init!,是因?yàn)樵诰幾g階段ConstClass.HELLOWORLD的值在編譯之后就被存入到NotIntialization的常量池中嗤练,因此編譯之后榛了,ConstClass和NotIntialization就沒(méi)有任何關(guān)系了,因此不會(huì)輸出ConstClass init!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末煞抬,一起剝皮案震驚了整個(gè)濱河市霜大,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌革答,老刑警劉巖战坤,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異残拐,居然都是意外死亡途茫,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)蹦骑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)慈省,“玉大人,你說(shuō)我怎么就攤上這事眠菇”甙埽” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵捎废,是天一觀的道長(zhǎng)笑窜。 經(jīng)常有香客問(wèn)我,道長(zhǎng)登疗,這世上最難降的妖魔是什么排截? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任嫌蚤,我火速辦了婚禮,結(jié)果婚禮上断傲,老公的妹妹穿的比我還像新娘脱吱。我一直安慰自己,他們只是感情好认罩,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布箱蝠。 她就那樣靜靜地躺著,像睡著了一般垦垂。 火紅的嫁衣襯著肌膚如雪宦搬。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天劫拗,我揣著相機(jī)與錄音间校,去河邊找鬼。 笑死页慷,一個(gè)胖子當(dāng)著我的面吹牛憔足,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播差购,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼四瘫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了欲逃?” 一聲冷哼從身側(cè)響起找蜜,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稳析,沒(méi)想到半個(gè)月后洗做,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡彰居,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年诚纸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陈惰。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡畦徘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出抬闯,到底是詐尸還是另有隱情井辆,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布溶握,位于F島的核電站杯缺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏睡榆。R本人自食惡果不足惜萍肆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一袍榆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧塘揣,春花似錦包雀、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至奴愉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間铁孵,已是汗流浹背锭硼。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蜕劝,地道東北人檀头。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像岖沛,于是被迫代替她去往敵國(guó)和親暑始。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容