java類加載過程

干Android開發(fā)兩年了,竟然不清楚Java類加載過程玄柠,都有點(diǎn)不好意思說自己會Java,這不趕快來惡補(bǔ)一下這方面的知識诫舅,搞明白類加載過程后羽利,會對其他技術(shù)知識譬如:static關(guān)鍵字的作用?反射機(jī)制刊懈?等等都有幫助这弧,這也是為什么知識一定要系統(tǒng)化的原因。

首先我們要了解一下ClassLoader虚汛,ClassLoader是Java用于加載類的一個機(jī)制匾浪。等到程序運(yùn)行時,JVM先初始化卷哩,在JVM初始化的過程中蛋辈,JVM生成幾個ClassLoader,JVM調(diào)用指定的ClassLoader去加載.class文件等各類路徑将谊、文件的類冷溶。
程序運(yùn)行時類的加載實(shí)際過程

1请垛、JDK執(zhí)行指令去尋找jre目錄叨粘,尋找jvm.dll赘理,并初始化JVM居兆;產(chǎn)生一個Bootstrap Loader(啟動類加載器);
2甘晤、Bootstrap Loader自動加載Extended Loader(標(biāo)準(zhǔn)擴(kuò)展類加載器)乳绕,并將其父Loader設(shè)為Bootstrap Loader享潜。
3瓦堵、Bootstrap Loader自動加載AppClass Loader(系統(tǒng)類加載器)柒巫,并將其父Loader設(shè)為Extended Loader。
4谷丸、最后由AppClass Loader加載Java類。

Java類加載過程即類裝載器把一個類裝入Java虛擬機(jī)中应结,總體來說包含以下過程:

編譯 -> 加載 -> 鏈接(驗(yàn)證+準(zhǔn)備+解析)->初始化(使用前的準(zhǔn)備)->使用-> 卸載

1刨疼、加載:以二進(jìn)制形式生成Class對象

⑴、通過一個類的全限定名來獲取定義此類的二進(jìn)制字節(jié)流鹅龄。
⑵揩慕、將這個字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時數(shù)據(jù)結(jié)構(gòu)。
⑶扮休、在java堆中生成一個代表這個類的java.lang.Class對象迎卤,作為方法區(qū)這些數(shù)據(jù)的訪問入口。

第一步獲取二進(jìn)制字節(jié)流有很多形式玷坠,因?yàn)樗]有限定二進(jìn)制流從哪里來蜗搔,那么我們可以 用系統(tǒng)的類加載器劲藐,也可以用自己的方式寫加載器來控制字節(jié)流的獲取 :

①從class文件來->一般的文件加載
②從zip包中來->加載jar中的類
③從網(wǎng)絡(luò)中來->Applet

獲取二進(jìn)制流獲取完成后會按照jvm所需的方式保存在方法區(qū)中,同時會在java堆中實(shí)例化一個java.lang.Class對象與堆中的數(shù)據(jù)關(guān)聯(lián)起來樟凄。

2聘芜、鏈接:又分驗(yàn)證、準(zhǔn)備缝龄、解析

⑴汰现、驗(yàn)證:檢查導(dǎo)入類或接口二進(jìn)制數(shù)據(jù)的正確
⑵ 、準(zhǔn)備:為靜態(tài)變量初始化并分配內(nèi)存地址
⑶叔壤、 解析:將符號引用轉(zhuǎn)為直接引用

第一步:驗(yàn)證

驗(yàn)證又可以細(xì)分一下幾個步驟: 文件格式驗(yàn)證->元數(shù)據(jù)驗(yàn)證->字節(jié)碼驗(yàn)證->符號引用驗(yàn)證

文件格式驗(yàn)證:驗(yàn)證字節(jié)流是否符合Class文件格式的規(guī)范并 驗(yàn)證其版本是否能被當(dāng)前的jvm版本所處理瞎饲。ok沒問題后,字節(jié)流就可以進(jìn)入內(nèi)存的方法區(qū)進(jìn)行保存了炼绘。后面的3個校驗(yàn)都是在方法區(qū)進(jìn)行的嗅战。
元數(shù)據(jù)驗(yàn)證 :對字節(jié)碼描述的信息進(jìn)行語義化分析,保證其描述的內(nèi)容符合java語言的語法規(guī)范饭望。
字節(jié)碼檢驗(yàn)
:最復(fù)雜仗哨,對方法體的內(nèi)容進(jìn)行檢驗(yàn),保證其在運(yùn)行時不會作出什么出格的事來铅辞。
符號引用驗(yàn)證 :來驗(yàn)證一些引用的真實(shí)性與可行性厌漂,比如代碼里面引了其他類,這里就要去檢測一下那些來究竟是否存在斟珊;或者說代碼中訪問了其他類的一些屬性苇倡,這里就對那些屬性的可以訪問行進(jìn)行了檢驗(yàn)。(這一步將為后面的解析工作打下基礎(chǔ))

驗(yàn)證的目的:確保class文件的字節(jié)流信息符合jvm的規(guī)范囤踩。假如jvm不對這些數(shù)據(jù)進(jìn)行校驗(yàn)的話旨椒,可能一些有害的字節(jié)流會讓jvm完全崩潰。
驗(yàn)證階段很重要堵漱,但也不是必要的综慎,假如說一些代碼被反復(fù)使用并驗(yàn)證過可靠性了,實(shí)施階段就可以嘗試用-Xverify:none參數(shù)來關(guān)閉大部分的類驗(yàn)證措施勤庐,以簡短類加載時間示惊。

第二步:準(zhǔn)備

這階段會為類變量(指那些靜態(tài)變量)分配內(nèi)存并設(shè)置類比那輛初始值的階段,這些內(nèi)存在方法區(qū)中進(jìn)行分配愉镰。這里要說明一下米罚,這一步只會給那些靜態(tài)變量設(shè)置一個初始的值,而那些實(shí)例變量是在實(shí)例化對象時進(jìn)行分配的丈探。
例如:

public static int value=123; 此時value的值為0录择,不是123。
private int i = 123; 此時,i 還未進(jìn)行初始化隘竭,因?yàn)檫@句代碼還不能執(zhí)行塘秦。

第三步:解析

是對類的屬性,方法等東西進(jìn)行轉(zhuǎn)換货裹,具體涉及到Class文件的格式內(nèi)容嗤形。

3、初始化:激活類的靜態(tài)變量和靜態(tài)代碼塊弧圆,初始化Java代碼

要對類進(jìn)行 初始化 赋兵,代碼上可以理解為 ‘為要初始化的類中的所有靜態(tài)成員都賦予初始值、對類中所有靜態(tài)塊都執(zhí)行一次搔预,并且是按代碼編寫順序執(zhí)行’ 霹期。
如下代碼:輸出的是‘1’。如果①和②順序調(diào)換拯田,則輸出的是‘123’历造。

public class Main {
 public static void main(String[] args){
 System.out.println(Super.i);
 }
}
class Super{
 //①
 static{
 i = 123;
 }
 //②
 protected static int i = 1;
}    

主動對類進(jìn)行引用”指的就是以下五種JVM規(guī)定的判定初始化與否的預(yù)處理?xiàng)l件。那么船庇,其他的方式吭产,都可歸為‘類被動引用’的方式,這些方式是不會引起JVM去初始化相關(guān)類的:

1.用new實(shí)例化一個類時

讀取或者設(shè)置類的靜態(tài)字段時(不包括被final修飾的靜態(tài)字段鸭轮,因?yàn)樗麄円呀?jīng)被塞進(jìn)常量池了)

2.執(zhí)行靜態(tài)方法的時候臣淤。

使用java.lang.reflect.*的方法對類進(jìn)行反射調(diào)用的時候,如果類還沒有進(jìn)行過初始化窃爷,馬上對其進(jìn)行邑蒋。

3.初始化一個類的時候,如果他的父親還沒有被初始化按厘,則先去初始化其父親医吊。
4.當(dāng)jvm啟動時

用戶需要指定一個要執(zhí)行的主類(包含static void main(String[] args)的那個類),則jvm會先去初始化這個類逮京。

5.用Class.forName(String className);來加載類的時候卿堂,也會執(zhí)行初始化動作。

注意:ClassLoader的loadClass(String className);方法只會加載并編譯某類懒棉,并不會對其執(zhí)行初始化

因此類從編譯御吞、被使用,到卸載的全過程:

編譯 -> 加載 -> 鏈接(驗(yàn)證+準(zhǔn)備+解析)->初始化(使用前的準(zhǔn)備)->使用-> 卸載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漓藕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子挟裂,更是在濱河造成了極大的恐慌享钞,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異栗竖,居然都是意外死亡暑脆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門狐肢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來添吗,“玉大人,你說我怎么就攤上這事份名〉” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵僵腺,是天一觀的道長鲤孵。 經(jīng)常有香客問我,道長辰如,這世上最難降的妖魔是什么普监? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮琉兜,結(jié)果婚禮上凯正,老公的妹妹穿的比我還像新娘。我一直安慰自己豌蟋,他們只是感情好廊散,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著夺饲,像睡著了一般奸汇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上往声,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天擂找,我揣著相機(jī)與錄音,去河邊找鬼浩销。 笑死贯涎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的慢洋。 我是一名探鬼主播塘雳,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼普筹!你這毒婦竟也來了败明?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤太防,失蹤者是張志新(化名)和其女友劉穎妻顶,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡讳嘱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年幔嗦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沥潭。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡邀泉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钝鸽,到底是詐尸還是另有隱情汇恤,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布寞埠,位于F島的核電站屁置,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仁连。R本人自食惡果不足惜蓝角,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望饭冬。 院中可真熱鬧使鹅,春花似錦、人聲如沸昌抠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽炊苫。三九已至裁厅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間侨艾,已是汗流浹背执虹。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留唠梨,地道東北人袋励。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像当叭,于是被迫代替她去往敵國和親茬故。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

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

  • 轉(zhuǎn)載請說明出處:Java面試相關(guān)(一)-- Java類加載全過程JVM判斷并裝載類的過程 概述: 我們知道蚁鳖,Jav...
    androidjp閱讀 7,911評論 3 92
  • 1.java類加載過程 重新回顧了java的類的生命周期磺芭,主要有:加載、鏈接醉箕、初始化钾腺、使用甘邀、卸載。上述過程包括了一...
    冬天里的懶喵閱讀 3,077評論 1 13
  • 今天突然在群里看到一段代碼垮庐,覺得挺有意思,先放出來看看 那么輸出結(jié)果是什么坞琴? 其實(shí)這主要就是考察到了Java類的加...
    阿阿阿阿嘞閱讀 287評論 0 0
  • 英孚家長: 您好哨查! 今天孩子學(xué)習(xí)了U1L7: 1.復(fù)習(xí)了前面學(xué)到的行為動作短語、時間狀態(tài)表達(dá) 2.學(xué)習(xí)完整句子的表...
    EmilyJia閱讀 164評論 0 0
  • 現(xiàn)在是銀杏剧辐,楓樹的季節(jié)寒亥,滿街飄零的落葉,被雨打濕的街道荧关,一股寒意襲來溉奕。告訴后知后覺的我們,已是后半個秋忍啤。 去年的你...
    Robiner閱讀 469評論 0 4