類加載過程


類加載的時機:

1.遇到new、getstatic骄呼、putstatic或invokestatic這4條字節(jié)碼指令時惰拱,如果類沒有進行過初始化,則需要先觸發(fā)其初始化凛虽。生成這4條指令的最常見的Java代碼場景是:使用new關(guān)鍵字實例化對象的時候死遭、讀取或設(shè)置一個類的靜態(tài)字段(被final修飾、已在編譯期把結(jié)果放入常量池的靜態(tài)字段除外)的時候凯旋,以及調(diào)用一個類的靜態(tài)方法的時候呀潭。

2.使用java.lang.reflect包的方法對類進行反射調(diào)用的時候钉迷,如果類沒有進行過初始化,則需要先觸發(fā)其初始化蜗侈。

3.當(dāng)初始化一個類的時候篷牌,如果發(fā)現(xiàn)其父類還沒有進行過初始化,則需要先觸發(fā)其父類的初始化踏幻。

4.當(dāng)虛擬機啟動時,用戶需要指定一個要執(zhí)行的主類(包含main()方法的那個類)戳杀,虛擬機會先初始化這個類该面。

5.當(dāng)使用JDK1.7的動態(tài)語言支持時,如果一個java.lang.invoke.MethodHandle實例最后的解析結(jié)果REF_getStatic信卡、REF_invokeStatic的方法句柄隔缀,并且這個方法句柄所對應(yīng)的類沒有進行過初始化,則需要先觸發(fā)其初始化傍菇。

類加載的過程:

1.加載:在加載階段猾瘸,虛擬機需要完成以下三件事情:

1)通過一個類的全限定名來獲取定義此類的二進制字節(jié)流。

2)將這個字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運行時數(shù)據(jù)結(jié)構(gòu)丢习。

3)在內(nèi)存中生成一個代表這個類的java.lang.Class對象牵触,作為方法區(qū)這個類的各種數(shù)據(jù)的訪問入口。

從上述要求來說咐低,加載這一過程的要求相對寬松揽思,因此虛擬機實現(xiàn)與具體應(yīng)用的靈活度都是相當(dāng)大的。例如“通過一個類的全限定名來獲取定義此類的二進制字節(jié)流”這條见擦,它沒有指明二進制字節(jié)流要從一個Class文件中獲取钉汗,準(zhǔn)確地說是根本沒有指明要從哪里獲取、怎樣獲取鲤屡。虛擬機設(shè)計團隊在加載階段搭建了一個相當(dāng)開放的损痰、廣闊的“舞臺”,java發(fā)展歷程中酒来,充滿創(chuàng)造力的開發(fā)人員則在這個“舞臺”上玩出了各種花樣卢未,許多舉足輕重的Java技術(shù)都建立在這一基礎(chǔ)之上。

加載階段完成后役首,虛擬機外部的二進制字節(jié)流就按照虛擬機所需的格式存儲在方法區(qū)之中尝丐,方法區(qū)中的數(shù)據(jù)存儲格式由虛擬機實現(xiàn)自行定義,虛擬機規(guī)范未規(guī)定此區(qū)域的具體數(shù)據(jù)結(jié)構(gòu)衡奥。然后在內(nèi)存中實例化一個java.lang.Class類的對象(并沒有明確規(guī)定是在Java堆中爹袁,對于HotSpot虛擬機而言,Class對象比較特殊矮固,它雖然是對象失息,但是存放在方法區(qū)里面)譬淳,這個對象將作為程序訪問方法區(qū)中的這些類型數(shù)據(jù)的外部接口。


2.驗證:驗證是連接階段的第一步盹兢,這一階段的目的是為了確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機的要求邻梆,并且不會危害虛擬機自身的安全。

Java語言本身是相對安全的語言绎秒,使用純粹的Java代碼無法做到諸如訪問數(shù)組邊界以外的數(shù)據(jù)浦妄、將一個對象轉(zhuǎn)型為它并為實現(xiàn)的類型,如果這樣做編譯器將拒絕執(zhí)行见芹,但前面已經(jīng)說過剂娄,Class文件并不一定要求用Java源碼編譯而來,可以使用任何途徑產(chǎn)生玄呛,甚至包括用十六進制編輯器直接編寫來產(chǎn)生Class文件阅懦。在字節(jié)碼層面上,上述Java代碼無法做到的事情都是可以實現(xiàn)的徘铝,至少語義上是可以表達(dá)出來的耳胎。

驗證階段的工作量在虛擬機的類加載子系統(tǒng)中非常重要,又占了相當(dāng)大的一部分惕它。

1.文件格式驗證:

? a.是否以魔數(shù)0xCAFEBABE開頭怕午;? ? ? ??

? b.主、次版本號是否在當(dāng)前虛擬機處理范圍之內(nèi)怠缸;??

? c.常量池的常量中是否有不被支持的常量類型诗轻;

2.元數(shù)據(jù)驗證:對字節(jié)碼描述的信息進行語義分析。

? ?a.這個類是否有父類揭北;

? ?b.這個類的父類是否繼承了不允許被繼承的類扳炬;

3.字節(jié)碼驗證:主要目的是通過數(shù)據(jù)流和控制流分析,確定程序語義是合法的搔体、符合邏輯的恨樟。將對類的方法體進行校驗分析,保證被校驗類的方法在運行時不會危害虛擬機疚俱。

? ? a.保證任意時刻操作數(shù)棧的數(shù)據(jù)類型與指令代碼序列都能配合工作劝术。

? ? b.保證跳轉(zhuǎn)指令不會跳轉(zhuǎn)到方法體以外的字節(jié)碼指令上。

4.符號引用驗證:對類自身以外的信息進行匹配性校驗呆奕。


3.準(zhǔn)備:準(zhǔn)備階段是正式為類變量分配內(nèi)存并設(shè)置類變量初始值的階段养晋,這些變量所使用的內(nèi)存都將在方法區(qū)中進行分配。

? ? ?這時候進行內(nèi)存分配的僅包括類變量(被static修飾的變量)梁钾,而不包括實例變量绳泉,實例變量將會在對象實例化時隨著對象一起分配在Java堆中,其次姆泻,這里所說的初始值“通常情況”下是數(shù)據(jù)類型的零值零酪。


4.解析:該階段是虛擬機將常量池內(nèi)的符號引用替換為直接引用的過程

符號引用:符號引用以一組符號來描述所飲用的目標(biāo)冒嫡,符號可以是任何形式的字面量,只要使用時能無歧義地定位到目標(biāo)即可四苇。符號引用與虛擬機實現(xiàn)的內(nèi)存布局無關(guān)孝凌,引用的目標(biāo)不一定已經(jīng)加載到內(nèi)存中。各種虛擬機實現(xiàn)的內(nèi)存布局可以各不相同月腋,但是他們能接受的符號引用必須都是一致的蟀架,因為符號引用的字面量形式明確定義在Java虛擬機規(guī)范的Class文件格式中。

直接引用:直接引用可以是直接指向目標(biāo)的指針罗售、相對偏移量或是一個能間接定位到目標(biāo)的句柄辜窑。直接引用是和虛擬機實現(xiàn)的內(nèi)存布局相關(guān)的,同一個符號引用在不同虛擬機實例上翻譯出來的直接引用一般不會相同寨躁。如果有了直接引用,那引用的目標(biāo)必定已經(jīng)在內(nèi)存中存在牙勘。

解析動作主要針對類或接口职恳、字段、類方法方面、接口方法放钦、方法句柄和調(diào)用點限定符。


5.初始化:前面的類加載過程中恭金,除了在加載階段用戶應(yīng)用程序可以通過自定義類加載器參與之外操禀,其余動作都是由虛擬機主導(dǎo)和控制。到了初始化階段横腿,才真正開始執(zhí)行類中定義的Java程序代碼颓屑。

? ? 在準(zhǔn)備階段,變量已經(jīng)賦過一次系統(tǒng)要求的初始值耿焊,而在初始化階段揪惦,則根據(jù)程序員通過程序定制的主觀計劃去初始化類變量和其他資源,或者可以從另外一個角度來表達(dá):初始化階段是執(zhí)行類構(gòu)造器<clinit>()方法的過程罗侯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末器腋,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子钩杰,更是在濱河造成了極大的恐慌纫塌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讲弄,死亡現(xiàn)場離奇詭異措左,居然都是意外死亡,警方通過查閱死者的電腦和手機垂睬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門媳荒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抗悍,“玉大人,你說我怎么就攤上這事钳枕〗稍ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵鱼炒,是天一觀的道長衔沼。 經(jīng)常有香客問我,道長昔瞧,這世上最難降的妖魔是什么指蚁? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮自晰,結(jié)果婚禮上凝化,老公的妹妹穿的比我還像新娘。我一直安慰自己酬荞,他們只是感情好搓劫,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著混巧,像睡著了一般枪向。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咧党,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天秘蛔,我揣著相機與錄音,去河邊找鬼傍衡。 笑死深员,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的聪舒。 我是一名探鬼主播辨液,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼箱残!你這毒婦竟也來了滔迈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤被辑,失蹤者是張志新(化名)和其女友劉穎燎悍,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盼理,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡谈山,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了宏怔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奏路。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡畴椰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鸽粉,到底是詐尸還是另有隱情斜脂,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布触机,位于F島的核電站帚戳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏儡首。R本人自食惡果不足惜片任,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蔬胯。 院中可真熱鬧对供,春花似錦、人聲如沸氛濒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泼橘。三九已至,卻和暖如春迈勋,著一層夾襖步出監(jiān)牢的瞬間炬灭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工靡菇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留重归,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓厦凤,卻偏偏與公主長得像鼻吮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子较鼓,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

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