還不懂java類加載機(jī)制的尝偎,建議看下這份阿里技術(shù)官總結(jié)的筆記饶火!

類加載機(jī)制

把class文件加載到內(nèi)存,并對數(shù)據(jù)進(jìn)行校驗(yàn)致扯,準(zhǔn)備肤寝,解析,初始化抖僵,形成可以被虛擬機(jī)直接使用的字節(jié)碼

類加載的時(shí)機(jī)(觸發(fā)類的初始化)

  • 使用new關(guān)鍵字實(shí)例化對象
  • 讀取一個(gè)類的靜態(tài)代碼塊
  • 使用java.lang.reflect包的方式對類進(jìn)行反射調(diào)用

類加載過程

整個(gè)生命周期包括:加載鲤看、校驗(yàn)、準(zhǔn)備耍群、解析义桂、初始化找筝、使用和卸載7個(gè)階段。

  1. 加載:通過一個(gè)類的全限定名來獲取定義此類的二進(jìn)制字節(jié)流慷吊,將這個(gè)字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)呻征,在內(nèi)存中生成一個(gè)代表這個(gè)類的Class對象,作為方法區(qū)這個(gè)類的各種數(shù)據(jù)的訪問入口
  2. 校驗(yàn):校驗(yàn)是連接階段的第一步罢浇,這一階段的目的是確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求陆赋,并且不會危害虛擬自身的安全。
  3. 準(zhǔn)備:準(zhǔn)備階段是正式為類變量分配內(nèi)存并設(shè)置類變量初始值的階段嚷闭,這些變量所使用的內(nèi)存都將在方法去中進(jìn)行分配攒岛。這時(shí)候進(jìn)行內(nèi)存分配的僅包括類變量(static),而不包括實(shí)例變量胞锰,實(shí)例變量將會在對象實(shí)例化時(shí)隨著對象一起分配在Java堆中灾锯。
  4. 解析:解析階段是虛擬機(jī)將常量池內(nèi)的符號(Class文件內(nèi)的符號)引用替換為直接引用(指針)的過程。
  5. 初始化:初始化階段是類加載過程的最后一步嗅榕,開始執(zhí)行類中定義的Java程序代碼(字節(jié)碼)顺饮。

加載

  • 通過全類名獲取class文件的二進(jìn)制字節(jié)流
  • 將字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)換為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
  • 生成一個(gè)代表該類的class對象,作為方法區(qū)這些數(shù)據(jù)的訪問入口
    根據(jù)字節(jié)碼在java堆中生成一個(gè)代表這個(gè)類的java.lang.Class對象

校驗(yàn)

  • 驗(yàn)證Class文件中二進(jìn)制字節(jié)流符合虛擬機(jī)的要求凌那,不會涉及到虛擬機(jī)的安全
  • 文件格式驗(yàn)證
  • 元數(shù)據(jù)驗(yàn)證
  • 字節(jié)碼驗(yàn)證

準(zhǔn)備

  • 為類變量分配內(nèi)存空間和設(shè)置初始值的階段
  • 為新生對象分配內(nèi)存

為新生對象分配內(nèi)存

  • 如果Java堆內(nèi)存是規(guī)整連續(xù)的兼雄,采用“指針碰撞”的分配方式
  • 如果不是連續(xù)規(guī)整的,采用“空閑列表”分配方式

內(nèi)存是否規(guī)整取決于垃圾收集器是否帶有壓縮整理功能

這個(gè)初始值和初始化階段的賦值不同帽蝶,這里指的是變量的默認(rèn)初始值赦肋,如果是final修飾的變量,就是賦予代碼里制定的初始值

解析

虛擬機(jī)將符號引用替換為直接引用的過程

符號引用 :符號引用以一組符號來描述所引用的目標(biāo)励稳。符號引用可以是任何形式的字面量佃乘,只要使用時(shí)能無歧義地定位到目標(biāo)即可,符號引用和虛擬機(jī)的布局無關(guān)驹尼。個(gè)人理解為:在編譯的時(shí)候一個(gè)每個(gè)java類都會被編譯成一個(gè)class文件趣避,但在編譯的時(shí)候虛擬機(jī)并不知道所引用類的地址,多以就用符號引用來代替新翎,而在這個(gè)解析階段就是為了把這個(gè)符號引用轉(zhuǎn)化成為真正的地址的階段程帕。

直接引用 :直接引用和虛擬機(jī)的布局是相關(guān)的,不同的虛擬機(jī)對于相同的符號引用所翻譯出來的直接引用一般是不同的料祠。如果有了直接引用骆捧,那么直接引用的目標(biāo)一定被加載到了內(nèi)存中澎羞。

初始化

根據(jù)程序代碼去初始化變量和其他資源髓绽,構(gòu)造函數(shù)

類加載器

BootstrapLoader/負(fù)責(zé)加載系統(tǒng)類

注意一個(gè)很重要的問題,就是java在邏輯上并不存在BootstrapKloader的實(shí)體妆绞,因?yàn)樗莄++編寫的顺呕,所以打印其內(nèi)容會是null

啟動類加載器主要加載 jre/lib下的jar文件枫攀。

ExtClassLoader/負(fù)責(zé)加載擴(kuò)展類//繼承類和實(shí)現(xiàn)類

擴(kuò)展類加載器主要加載 jre/lib/ext 下的jar文件。

AppClassLoader/負(fù)責(zé)加載應(yīng)用類

應(yīng)用程序類加載器主要加載 classpath 下的文件

Android類加載器

對于Android而言株茶,最終的apk文件包含的是dex類型的文件来涨,dex文件是將class文件重新打包,打包的規(guī)則又不是簡單地壓縮启盛,而是完全對class文件內(nèi)部的各種函數(shù)表蹦掐,變量表進(jìn)行優(yōu)化,產(chǎn)生一個(gè)新的文件僵闯,即dex文件卧抗。因此加載這種特殊的Class文件就需要特殊的類加載器DexClassLoader。

雙親委派模型

當(dāng)加載一個(gè)類時(shí)鳖粟,會優(yōu)先使用父類加載器加載社裆,當(dāng)父類加載器無法加載時(shí)才會使用子類加載器去加載。這么做的目的是為了避免類的重復(fù)加載

解釋器

對字節(jié)碼逐條解釋執(zhí)行向图,這種方式的執(zhí)行速度相對會比較慢泳秀;重復(fù)執(zhí)行需要重復(fù)解釋

JIT(即時(shí)編譯器)

在運(yùn)行時(shí),虛擬機(jī)將會把這些頻繁調(diào)用的代碼編譯成與本地平臺相關(guān)的機(jī)器碼榄攀,并進(jìn)行優(yōu)化嗜傅,可重復(fù)執(zhí)行,緩存效率高

Class文件字節(jié)碼結(jié)構(gòu)

魔數(shù)—副版本號—主版本號—常量池計(jì)數(shù)器—常量池?cái)?shù)據(jù)區(qū)—訪問標(biāo)志—類索引—父類索引—接口計(jì)數(shù)器—接口信息數(shù)據(jù)區(qū)—字段計(jì)數(shù)器—字段信息數(shù)據(jù)區(qū)—方法計(jì)數(shù)器—方法信息數(shù)據(jù)區(qū)—屬性計(jì)數(shù)器—屬性信息數(shù)據(jù)區(qū)

魔數(shù):class文件的標(biāo)志檩赢,確定這個(gè)文件是否為一個(gè)能被虛擬機(jī)接收的class文件

類B繼承A磺陡,A、B兩個(gè)類中都有靜態(tài)變量漠畜、成員變量币他、靜態(tài)代碼塊、構(gòu)造方法執(zhí)行順序是什么憔狞?

1.父類【靜態(tài)成員】和【靜態(tài)代碼塊】蝴悉,按在代碼中出現(xiàn)的順序依次執(zhí)行。
2.子類【靜態(tài)成員】和【靜態(tài)代碼塊】瘾敢,按在代碼中出現(xiàn)的順序依次執(zhí)行拍冠。
3.父類的【普通成員變量被普通成員方法賦值】和【普通代碼塊】,按在代碼中出現(xiàn)的順序依次執(zhí)行簇抵。
4.執(zhí)行父類的構(gòu)造方法庆杜。
5.子類的【普通成員變量被普通成員方法賦值】和【普通代碼塊】,按在代碼中出現(xiàn)的順序依次執(zhí)行碟摆。
6.執(zhí)行子類的構(gòu)造方法晃财。

JVM在搜索類的時(shí)候,又是如何判定兩個(gè)class是相同的呢典蜕?

JVM在判定兩個(gè)class是否相同時(shí)断盛,不僅要判斷兩個(gè)類名是否相同罗洗,而且要判斷是否由同一個(gè)類加載器實(shí)例加載的。只有兩者同時(shí)滿足的情況下钢猛,JVM才認(rèn)為這兩個(gè)class是相同的伙菜。

就算兩個(gè)class是同一份class字節(jié)碼,如果被兩個(gè)不同的ClassLoader實(shí)例所加載命迈,JVM也會認(rèn)為它們是兩個(gè)不同class贩绕。

類的加載過程,Person person = new Person();為例進(jìn)行說明壶愤。

1).因?yàn)閚ew用到了Person.class丧叽,所以會先找到Person.class文件,并加載到內(nèi)存中;
2).執(zhí)行該類中的static代碼塊公你,如果有的話踊淳,給Person.class類進(jìn)行初始化;
3).在堆內(nèi)存中開辟空間分配內(nèi)存地址;
4).在堆內(nèi)存中建立對象的特有屬性,并進(jìn)行默認(rèn)初始化;
5).對屬性進(jìn)行顯示初始化;
6).對對象進(jìn)行構(gòu)造代碼塊初始化;
7).對對象進(jìn)行與之對應(yīng)的構(gòu)造函數(shù)進(jìn)行初始化;
8).將內(nèi)存地址付給棧內(nèi)存中的p變量

class實(shí)例和class對象的區(qū)別

java有兩種對象:實(shí)例對象和Class對象陕靠。
每個(gè)類的運(yùn)行時(shí)的類型信息就是用Class對象表示的迂尝。它包含了與類有關(guān)的信息。
其實(shí)我們的實(shí)例對象就通過Class對象來創(chuàng)建的

有三種獲得Class對象的方式:

  • Class.forName(“類的全限定名”)
  • 實(shí)例對象.getClass()
  • 類名.class (類字面常量)

實(shí)例newInstance()

最后

看完有什么不懂的可以在評論區(qū)問我剪芥,覺得對你有幫助的話記得給我點(diǎn)個(gè)贊垄开!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市税肪,隨后出現(xiàn)的幾起案子溉躲,更是在濱河造成了極大的恐慌,老刑警劉巖益兄,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锻梳,死亡現(xiàn)場離奇詭異,居然都是意外死亡净捅,警方通過查閱死者的電腦和手機(jī)疑枯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛔六,“玉大人荆永,你說我怎么就攤上這事」拢” “怎么了具钥?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長液兽。 經(jīng)常有香客問我骂删,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任桃漾,我火速辦了婚禮坏匪,結(jié)果婚禮上拟逮,老公的妹妹穿的比我還像新娘撬统。我一直安慰自己,他們只是感情好敦迄,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布恋追。 她就那樣靜靜地躺著,像睡著了一般罚屋。 火紅的嫁衣襯著肌膚如雪苦囱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天脾猛,我揣著相機(jī)與錄音撕彤,去河邊找鬼。 笑死猛拴,一個(gè)胖子當(dāng)著我的面吹牛羹铅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播愉昆,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼职员,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了跛溉?” 一聲冷哼從身側(cè)響起焊切,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芳室,沒想到半個(gè)月后专肪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡堪侯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年牵祟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抖格。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诺苹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雹拄,到底是詐尸還是另有隱情收奔,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布滓玖,位于F島的核電站坪哄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜翩肌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一模暗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧念祭,春花似錦兑宇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至站玄,卻和暖如春枚驻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背株旷。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工再登, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晾剖。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓锉矢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親钞瀑。 傳聞我的和親對象是個(gè)殘疾皇子沈撞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348