類的加載過(guò)程

ClassLoader主要職責(zé)就是加載各種class文件到JVM中匆骗,他是一個(gè)抽象的類,給定一個(gè)class的二進(jìn)制文件名椒涯,他會(huì)嘗試加載并且在Jvm中生成構(gòu)成這個(gè)類的各個(gè)數(shù)據(jù)結(jié)構(gòu)柄沮,然后使其分布在Jvm對(duì)應(yīng)的內(nèi)存區(qū)域中。

類的加載過(guò)程分為三個(gè)階段废岂,加載階段祖搓,連接階段,和初始化階段

加載階段

主要負(fù)責(zé)查找并且加載類的二進(jìn)制文件湖苞,其實(shí)就是class文件拯欧,將class文件中的二進(jìn)制數(shù)據(jù)讀取到內(nèi)存中,然后將該字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)換為方法區(qū)中運(yùn)行時(shí)的數(shù)據(jù)結(jié)構(gòu)财骨,并且在堆中生成一個(gè)該類的class對(duì)象作為訪問(wèn)方法區(qū)數(shù)據(jù)結(jié)構(gòu)的入口

棧內(nèi)存:ClassLoader的引用镐作,Aclass對(duì)象的引用藏姐,A對(duì)象的引用
堆內(nèi)存:ClassLoader對(duì)象,A的class對(duì)象该贾,A對(duì)象
方法區(qū):A類的數(shù)據(jù)結(jié)構(gòu)

不管某個(gè)類被加載了多少次羔杨,對(duì)應(yīng)到堆內(nèi)存中的class對(duì)象始終是同一個(gè),他是類加載的最終產(chǎn)物杨蛋。

連接階段分為三個(gè)部分:驗(yàn)證兜材、準(zhǔn)備、解析

驗(yàn)證:

1.驗(yàn)證文件格式

  • 二進(jìn)制文件頭部的魔術(shù)因子逞力,該因子決定了文件是什么類型
  • 主次版本號(hào)曙寡,高版本的Jvm編譯的class不能被低版本的Jvm所兼容
  • class文件的字節(jié)流是否殘缺(每個(gè)類在編譯的時(shí)候會(huì)經(jīng)過(guò)md5摘要算法之后會(huì)作為字節(jié)流的一部分)
  • 常量池中的常量是否存在不被支持的變量類型
  • 指向常量的引用是否指到了不存在的常量或者該常量的類型不被支持
  1. 元數(shù)據(jù)的驗(yàn)證(對(duì)class的字節(jié)流進(jìn)行語(yǔ)義分析,確保符合Jvm規(guī)范)
  • 檢查這個(gè)類是否存在父類寇荧,是否繼承了某個(gè)接口举庶,這些父類和接口是否合法或者存在
    -檢查該類是否繼承了被final修飾的類,被final修飾的類是不允許被繼承的砚亭,并且其中的方法是不允許被覆蓋的
  • 檢查該類是否是抽象類灯变,如果不是,是否實(shí)現(xiàn)了父類的抽象接口中的所有方法
  • 檢查方法重載的合法性捅膘,比如相同的方法名稱添祸,參數(shù)但是返回類型不相同是不被允許的
  1. 字節(jié)碼的驗(yàn)證
  • 保證當(dāng)前線程在程序計(jì)數(shù)器中的指令不會(huì)跳轉(zhuǎn)到不合法的字節(jié)碼指令
  • 保證類型的轉(zhuǎn)換是否合法,比如用A聲明的引用寻仗,不能用B進(jìn)行強(qiáng)制轉(zhuǎn)換
    -保證任意時(shí)刻刃泌,虛擬機(jī)棧中的操作棧類型與指令代碼都能正確的被執(zhí)行,比如壓棧的時(shí)候傳入的是A類型的引用署尤,在使用的時(shí)候卻將B類型載入了本地變量表
  1. 符號(hào)引用驗(yàn)證(主要是驗(yàn)證某個(gè)類的字段不存在耙替,或者方法不存在拋出異常,反射的時(shí)候比較多見(jiàn))
  • 通過(guò)符號(hào)引用描述的字符串全限定名稱是否能夠順利的找到相關(guān)的類
  • 符號(hào)引用中的類曹体,方法俗扇,字段,是否對(duì)當(dāng)前類可見(jiàn)箕别,比如不能訪問(wèn)引用類的私有方法
    5.其他驗(yàn)證
準(zhǔn)備:

當(dāng)一個(gè)class的字節(jié)流通過(guò)了所有的準(zhǔn)備驗(yàn)證過(guò)程之后铜幽,就開(kāi)始為該對(duì)象的類變量(靜態(tài)變量)分配內(nèi)存且設(shè)置初始值,類變量的內(nèi)存會(huì)被分配到方法區(qū)中串稀,不同于實(shí)例變量會(huì)被分配到堆內(nèi)存中除抛,所謂分配初始值,就是為相應(yīng)的類變量給定一個(gè)相關(guān)類型在沒(méi)有被設(shè)置值時(shí)的默認(rèn)值
public static int a=10,在連接階段初始值是0,
public final static int b=10,不會(huì)導(dǎo)致類的初始化母截,是一種被動(dòng)引用到忽,他不存在連接階段,他在編譯階段就會(huì)被直接賦值為10

解析:

Simple simple=new Simple();
System.out.println(simple.name());
如上 我們可以通過(guò)simple訪問(wèn)Simple中的可見(jiàn)屬性和方法清寇,但是在字節(jié)碼中喘漏,他會(huì)被編譯成相應(yīng)的助記符(符號(hào)引用)护蝶,在類的解析過(guò)程中助記符還需要進(jìn)一步解析才能正確的找到所對(duì)應(yīng)的堆內(nèi)存中的Simple數(shù)據(jù)結(jié)構(gòu)。

  • 字段解析
    在解析類或者變量的時(shí)候比如上述Simple在調(diào)用他的屬性和方法的時(shí)候陷遮,如果該字段不存在滓走,或者出現(xiàn)錯(cuò)誤就會(huì)拋出異常
    如果Simple中本身就包含這個(gè)字段,則直接返回這個(gè)字段的引用帽馋,當(dāng)然也要對(duì)該字段所屬的類提前進(jìn)行類加載
    如果Simple中沒(méi)有該字段,則會(huì)根據(jù)繼承關(guān)系自下而上比吭,查找父類或者接口的字段绽族,找到即可返回,同樣也需要提前對(duì)找到的字段進(jìn)行類的加載過(guò)程
    如果Simple中沒(méi)有字段衩藤,一直找到了Object還是沒(méi)有吧慢,則表示查找失敗,直接拋出異常
    這就解釋了子類為什么重寫(xiě)了父類的字段之后能夠生效的原因赏表,因?yàn)檎业阶宇惖淖侄尉椭苯映跏蓟祷亓?/li>
  • 類方法的解析
    類方法和接口不同检诗,類方法可以直接使用該類調(diào)用,接口方法必須要有相應(yīng)的實(shí)現(xiàn)類繼承才能夠進(jìn)行調(diào)用
    若在類方法表中發(fā)現(xiàn)索引的Simple是一個(gè)接口不是一個(gè)類瓢剿,則直接返回錯(cuò)誤
    在Simple中查找是否有目標(biāo)方法逢慌,如果有直接返回該方法的引用,否則繼續(xù)向上查找
    如果父類中仍然沒(méi)有找到則拋出異常
    如果在當(dāng)前類或者父類中找到了目標(biāo)方法间狂,但是它是一個(gè)抽象類攻泼,則也會(huì)拋出異常
  • 接口方法的解析
    接口不僅可以定義方法,還可以繼承其他接口
    如果在接口方法表中發(fā)現(xiàn)索引的simple是一個(gè)類而不是接口鉴象,則會(huì)直接返回錯(cuò)誤忙菠,因?yàn)榉椒ń涌诒砗皖惤涌诒硭菁{的類型應(yīng)該是不一樣的
    接下來(lái)的查找就和類方法的解析比較類似了,自下而上查找纺弊,直到找到為止牛欢,如果沒(méi)有拋出異常
  • 類接口的解析
    如果simple是一個(gè)數(shù)組類型,則虛擬機(jī)不需要完成對(duì)simple的加載淆游,只需要在虛擬機(jī)中生成一個(gè)能夠代表該類型的對(duì)象傍睹,并且在堆內(nèi)存中開(kāi)辟一片連續(xù)的地址空間即可

初始化階段主要為類的靜態(tài)變量賦予正確的初始值(代碼編寫(xiě)階段給定的值)

每個(gè)類或者接口被java程序首次主動(dòng)使用時(shí),JVM才會(huì)對(duì)其進(jìn)行初始化,所以程序包中那么多類并不是一次性全部被JVM初始化的稽犁,他很lazy.
靜態(tài)語(yǔ)句塊只能對(duì)后面的靜態(tài)變量賦值焰望,不能訪問(wèn),否則無(wú)法通過(guò)編譯
static{
System.out.println(x);
x=100;
}
private static int x=10;
虛擬機(jī)會(huì)保證父類的<clinit>方法最先執(zhí)行,因此父類的靜態(tài)變量總是能夠得到優(yōu)先賦值

主動(dòng)使用的場(chǎng)景如下:

1.通過(guò)new關(guān)鍵字(會(huì)導(dǎo)致類的加載和最終初始化)TestApplication test=new TestApplication();
2.訪問(wèn)類的靜態(tài)變量,讀取和更新都會(huì)導(dǎo)致類的初始化 public static int x=10;但是已亥,要記住熊赖,引用類的靜態(tài)常量不會(huì)導(dǎo)致類被初始化,如 public final static int x=10;他是一個(gè)常量虑椎,不過(guò)需要計(jì)算的常量如:public final static int RANDOM=new Random().nextInt()例外震鹉,由于他在類的加載和和連接階段無(wú)法對(duì)其進(jìn)行計(jì)算俱笛,需要進(jìn)行初始化后才能對(duì)其賦值。
3.訪問(wèn)類的靜態(tài)方法也會(huì)導(dǎo)致類的初始化
4.對(duì)某個(gè)類進(jìn)行反射操作會(huì)導(dǎo)致類的初始化 Class.forName("packageName+ClassName");
5.初始化子類會(huì)導(dǎo)致父類也被初始化传趾,比如訪問(wèn)子類的靜態(tài)變量或者靜態(tài)方法迎膜,或者new一個(gè)子類,都會(huì)導(dǎo)致父類也被初始化浆兰,但是通過(guò)子類使用父類的靜態(tài)變量或者靜態(tài)方法只會(huì)導(dǎo)致父類被初始化磕仅,子類不會(huì)被初始化

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市簸呈,隨后出現(xiàn)的幾起案子榕订,更是在濱河造成了極大的恐慌,老刑警劉巖蜕便,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劫恒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡轿腺,警方通過(guò)查閱死者的電腦和手機(jī)两嘴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)族壳,“玉大人憔辫,你說(shuō)我怎么就攤上這事【龀蓿” “怎么了螺垢?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)赖歌。 經(jīng)常有香客問(wèn)我枉圃,道長(zhǎng),這世上最難降的妖魔是什么庐冯? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任孽亲,我火速辦了婚禮,結(jié)果婚禮上展父,老公的妹妹穿的比我還像新娘返劲。我一直安慰自己,他們只是感情好栖茉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布篮绿。 她就那樣靜靜地躺著,像睡著了一般吕漂。 火紅的嫁衣襯著肌膚如雪亲配。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音吼虎,去河邊找鬼犬钢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛思灰,可吹牛的內(nèi)容都是我干的玷犹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼洒疚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼歹颓!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起油湖,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤晴股,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后肺魁,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡隔节,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年鹅经,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怎诫。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瘾晃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出幻妓,到底是詐尸還是另有隱情蹦误,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布肉津,位于F島的核電站强胰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏妹沙。R本人自食惡果不足惜偶洋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望距糖。 院中可真熱鬧玄窝,春花似錦、人聲如沸悍引。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)趣斤。三九已至俩块,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背典阵。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工奋渔, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人壮啊。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓嫉鲸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親歹啼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子玄渗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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