深入理解java中的類加載器

? ? java類加載器是將java class字節(jié)碼加載到內(nèi)存中的組件胚嘲,分為引導(dǎo)類加載器(bootstrapClassLoader)、擴(kuò)展加載器(ExtensionClassLoader)否淤、應(yīng)用類加載器(appClassLoader)下面分別介紹這三種類加載器。

? ? 1.引導(dǎo)類加載器(bootStrapClassLoader)

? ?引導(dǎo)類加載器是有c++編寫,主要作用為加載java環(huán)境本身需要的class,主要包含java_home/lib 目錄下java核心類庫(kù)疙剑,以及-xbootclasspath參數(shù)指定的類庫(kù),值得注意的是該類加載器只加載jdk本身的類庫(kù)稽煤,即使在lib目錄下放入新的jar包核芽,該類加載也不會(huì)加載。該類加載器要求加載的類包頭還必須是sun酵熙、java轧简、javax。

? ? 2.擴(kuò)展類加載器(extensionClassLoader)

? ? 開發(fā)者可以直接使用擴(kuò)展類加載器匾二,該加載器負(fù)責(zé)加載java_home/lib/ext目錄下類庫(kù)哮独。開發(fā)者也可以使用擴(kuò)展類加載器加載-Djava.ext.dir指定目錄下的類庫(kù)拳芙。

? ? 3.應(yīng)用類加載器(appClassLoader)

? ? 應(yīng)用類加載器主要用于加載系統(tǒng)應(yīng)用的class文件。它負(fù)責(zé)加載系統(tǒng)類路徑j(luò)ava -classpath或-D java.class.path?指定路徑下的類庫(kù)皮璧,也就是我們經(jīng)常用到的classpath路徑舟扎,開發(fā)者可以直接使用系統(tǒng)類加載器,一般情況下該類加載是程序中默認(rèn)的類加載器悴务,通過getSystemClassLoader()方法可以獲取到該類加載器睹限。?

 Java虛擬機(jī)對(duì)class文件采用的是按需加載的方式,也就是說當(dāng)需要使用該類時(shí)才會(huì)將它的class文件加載到內(nèi)存生成class對(duì)象讯檐,而且加載某個(gè)類的class文件時(shí)羡疗,Java虛擬機(jī)采用的是雙親委派模式即把加載類的動(dòng)作交由父類處理,是一種任務(wù)委派模式别洪。

????雙親委派模式

? ? 在java中類加載器被要求都要有父加載器叨恨,除了頂層的引導(dǎo)類加載器。但是雙親委派模式中的父子關(guān)系并非所說的類繼承關(guān)系中的父子挖垛,而是采用一種組合的關(guān)系復(fù)用父加載器的代碼痒钝。


圖1



圖2

但是當(dāng)你看java jdk這幾個(gè)類源碼是通常會(huì)有困惑,因?yàn)樗麄兊睦^承關(guān)系并非如圖1所示痢毒,而是如圖2所示送矩,這是因?yàn)樯厦嫠f的雙親委托中的雙親和兒子并不是指類繼承關(guān)系中的父類,而是以調(diào)用優(yōu)先順序來表示的父子關(guān)系闸准。如appClassLoader中的parent屬性指向了extClassLoader益愈,我們稱extClassLoader在雙親委托模式中是appClassLoader的父加載器。假設(shè)我們自定義一個(gè)MyClassLoader繼承ClassLoader類夷家,我們發(fā)現(xiàn)MyClassLoader中的parent依然指向的是appClassLoader蒸其。也就是說在類關(guān)系圖中,MyClassLoader是ClassLoader的子類库快,但是在雙親委托模式鏈中MyClassLoader是AppClassLoader的子節(jié)點(diǎn)摸袁。這是為什么呢?我們來看下ClassLoader的構(gòu)造函數(shù)

圖3

如圖ClassLoader類在沒有顯試指定父節(jié)點(diǎn)(parent)是誰的時(shí)候义屏,默認(rèn)是Launcher.getClassLoader()獲取靠汁,即AppClassLoader,至此真相大白闽铐!

tip

tip1蝶怔、類加載器與main方法 與jjava進(jìn)程之間的關(guān)系。

當(dāng)我們啟動(dòng)一個(gè)Java程序兄墅,即啟動(dòng)一個(gè)main方法時(shí)踢星,都將啟動(dòng)一個(gè)Java虛擬機(jī)進(jìn)程,不管這個(gè)進(jìn)程有多么復(fù)雜隙咸。而不同的JVM進(jìn)程之間是不會(huì)相互影響的沐悦。這也就是為什么說成洗,Java程序只有一個(gè)入口——main方法,讓虛擬機(jī)調(diào)用藏否。而兩個(gè)mian方法瓶殃,對(duì)應(yīng)的是2個(gè)JVM進(jìn)程,啟動(dòng)的是兩個(gè)不同的類加載器副签,操作的實(shí)際上是不同的類遥椿。故而不會(huì)互相影響。

tip2继薛、之前看完java類加載器的關(guān)系修壕,一直心里有疑惑愈捅,覺得哪里有什么問題遏考,又不知道問題在哪,看完tomcat的類加載機(jī)制蓝谨,在寫這些文章的時(shí)候灌具,想明白了問題和答案。我發(fā)現(xiàn)在寫東西的時(shí)候能更好的梳理邏輯譬巫。問題如下:如果java按照雙親委派模式加載類咖楣,那豈不是所有的類都會(huì)被最頂層的類加載器所加載?bootStrap顯然不會(huì)只會(huì)加載核心類包 (rt.jar),ExtClassLoader也是會(huì)加載ext目錄下jar包芦昔,那么AppClassLoader呢诱贿?我猜AppClassLoader會(huì)加載main函數(shù)所在classpath。另外所有的自定義classloader都會(huì)加載指定目錄下class咕缎,這樣就不會(huì)出現(xiàn)所有class都由AppClassLoader加載的情況了珠十。證據(jù)如下URLclassLoader的構(gòu)造函數(shù)如下:

說明構(gòu)造函數(shù)

說明classLoader需要指定類加載路徑。

tip3凭豪、一個(gè)應(yīng)用里類靜態(tài)變量永遠(yuǎn)只有一個(gè)值嗎焙蹭?

我們都知道靜態(tài)變量屬于類,所有的對(duì)象共享一個(gè)值嫂伞。在了解java類加載器之前孔厉,一直認(rèn)為一個(gè)靜態(tài)變量在一個(gè)應(yīng)用里只有一個(gè)值。但是學(xué)習(xí)完java類加載后就想到可能不是帖努,如果這個(gè)類被兩個(gè)類加載器加載撰豺,那么它的靜態(tài)變量就可能有兩個(gè)值。我們寫個(gè)程序來驗(yàn)證下拼余,如下:


測(cè)試代碼
測(cè)試結(jié)果

可以看到污桦,當(dāng)兩個(gè)類加載器分別加載了class后,class對(duì)象不是同一個(gè)姿搜。通過反射把c1的say值改為hello2寡润,c2的say值還是hello捆憎。驗(yàn)證完畢。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末梭纹,一起剝皮案震驚了整個(gè)濱河市躲惰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌变抽,老刑警劉巖础拨,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異绍载,居然都是意外死亡诡宗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門击儡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來塔沃,“玉大人,你說我怎么就攤上這事阳谍≈瘢” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵矫夯,是天一觀的道長(zhǎng)鸽疾。 經(jīng)常有香客問我,道長(zhǎng)训貌,這世上最難降的妖魔是什么制肮? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮递沪,結(jié)果婚禮上豺鼻,老公的妹妹穿的比我還像新娘。我一直安慰自己区拳,他們只是感情好拘领,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著樱调,像睡著了一般约素。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上笆凌,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天圣猎,我揣著相機(jī)與錄音,去河邊找鬼乞而。 笑死送悔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播欠啤,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼荚藻,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了洁段?” 一聲冷哼從身側(cè)響起应狱,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎祠丝,沒想到半個(gè)月后疾呻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡写半,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年岸蜗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叠蝇。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡璃岳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蟆肆,到底是詐尸還是另有隱情矾睦,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布炎功,位于F島的核電站,受9級(jí)特大地震影響缓溅,放射性物質(zhì)發(fā)生泄漏蛇损。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一坛怪、第九天 我趴在偏房一處隱蔽的房頂上張望淤齐。 院中可真熱鬧,春花似錦袜匿、人聲如沸更啄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祭务。三九已至,卻和暖如春怪嫌,著一層夾襖步出監(jiān)牢的瞬間义锥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工岩灭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拌倍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像柱恤,于是被迫代替她去往敵國(guó)和親数初。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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