激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - java類的加載過程以及類加載器的分析

java類的加載過程以及類加載器的分析

2021-05-23 15:08world6 Java教程

這篇文章給大家詳細(xì)講述了java類的加載過程以及類加載器的相關(guān)知識點(diǎn)內(nèi)容,有需要的朋友可以學(xué)習(xí)下。

我們知道,我們寫的java代碼保存的格式是 .java, java文件被編譯后會轉(zhuǎn)換為字節(jié)碼,字節(jié)碼可以在任何平臺通過java虛擬機(jī)來運(yùn)行,這也是java能夠跨平臺的原因。

那jvm是如何來讓我們寫的java文件運(yùn)行的呢? 這個(gè)問題通常的問法好像是:是如何被加載的。

記得第一次遇見這個(gè)問題的時(shí)候,同學(xué)給我的回答是:

1.虛擬機(jī)會加載jdk里類的核心包

2.虛擬機(jī)會加載jdk里類的擴(kuò)展包

3.虛擬機(jī)會加載jdk里類的系統(tǒng)包

4.虛擬機(jī)再會加載我們寫好的java類。

初學(xué)的時(shí)候,大家都這么說,好像也沒發(fā)現(xiàn)什么錯(cuò)。 最近在瀏覽一些博客時(shí)看到一些更為詳細(xì)的講解,如java類加載全過程,該博文有一萬多的點(diǎn)擊,但感覺還是講得不夠詳細(xì),說了類的加載過程有哪些,但沒有詳細(xì)的展開,說了一些類初始化的細(xì)節(jié)。 在翻讀《深入理解java虛擬機(jī)》209-235頁后,總結(jié)了其內(nèi)容,談?wù)勛约簩υ摬糠值睦斫獍伞?/p>

希望大家看了之后更能理解jvm的工作原理和java類的生產(chǎn)過程(類加載的過程);

類從被加載到虛擬機(jī)類存中開始,到被卸載出內(nèi)存為止,它的整個(gè)生命周期包括

加載 → 驗(yàn)證 → 準(zhǔn)備 → 解析 → 初始化 → 使用 → 卸載 7個(gè)部分、

下面我就來詳細(xì)的說說每個(gè)部分的詳細(xì)過程,再補(bǔ)充一下雙親委派模型。

再次之前我想補(bǔ)充一個(gè)名詞解釋,類加載器:虛擬機(jī)把 實(shí)現(xiàn) 類加載階段中的“通過一個(gè)類的全限定名來獲取描述此類的二進(jìn)制字節(jié)流” 這個(gè)過程的代碼稱為類加載器

1. 加載

加載只是類加載過程的一個(gè)階段而已,但往往被大家弄成了這就是類的加載過程,所以才有了博文開頭時(shí)同學(xué)給我的那個(gè)回答;

希望大家不要混淆出這個(gè)很相似的名詞,從而對類加載有所誤讀。

1.jdk在執(zhí)行程序運(yùn)行命令時(shí)會去jre目錄中找到j(luò)vm.dll , 并初始化jvm

這時(shí)會產(chǎn)生一個(gè)bootstrap loader(啟動(dòng)類加載器)

2.bootstrap loader 自動(dòng)加載 extended loader(標(biāo)準(zhǔn)擴(kuò)展類加載器)

3.bootstrap loader 自動(dòng)加載 appclass loader(系統(tǒng)類加載器)

4.最后由 appclass loader 加載 我們指定(想要運(yùn)行)的 java 類

這里可以提一下雙親委派模型加載類的方式:

實(shí)現(xiàn)雙親委派的代碼都集中在java.lang.classloader的 loadclass()方法中, 源碼我就不貼出來了;

其源碼大概意思如下:

1.先檢查此類是否被加載過,若沒有加載則調(diào)用父加載器的loadclass()方法,

2.若父加載器為空,則默認(rèn)使用啟動(dòng)類加載器作為父加載器,

3.若父類加載失敗,會拋出一個(gè)異常,然后再調(diào)用自己的findclass()方法來進(jìn)行加載;

結(jié)合第一步加載可以這么理解,

1.首先要啟動(dòng)→ 啟動(dòng)類加載器,這時(shí)會調(diào)用啟動(dòng)類加載器的父加載器,但由于啟動(dòng)類加載器時(shí)所有類的父加載器,
所以其父加載器為空(相當(dāng)于object是所有類的父類,這種感腳~),然后它就會調(diào)用自己的findclass方法來自啟動(dòng)加載 ;

2.標(biāo)準(zhǔn)擴(kuò)展類加載器啟動(dòng)時(shí)就會借助其父類 啟動(dòng)類加載器 作為父加載器 來啟動(dòng)了;

3.系統(tǒng)類加載器啟動(dòng)時(shí)就會借助其父類 標(biāo)準(zhǔn)擴(kuò)展類加載器 作為父加載器 來啟動(dòng)了;

4.最后我們編寫的普通類就會借助其父類 系統(tǒng)類加載器 作為父加載器 來啟動(dòng)了;

2.驗(yàn)證

驗(yàn)證主要分為以下幾個(gè)步驟:文件格式驗(yàn)證->元數(shù)據(jù)驗(yàn)證->字節(jié)碼驗(yàn)證->符號引用驗(yàn)證

1.文件格式驗(yàn)證:主要是檢查字節(jié)碼的字節(jié)流是否符合class文件格式的規(guī)范,驗(yàn)證該文件是否能被當(dāng)前的 jvm 所處理,
如果沒問題,字節(jié)里就可以進(jìn)入方法區(qū)進(jìn)行保存了;

2.元數(shù)據(jù)驗(yàn)證:對字節(jié)碼描述的信息進(jìn)行語義分析,保證其描述的內(nèi)容符合java語言的語法規(guī)范,能被java虛擬機(jī)識別;

3.字節(jié)碼驗(yàn)證:該部分最為復(fù)雜,對方法體內(nèi)的內(nèi)容進(jìn)行驗(yàn)證,保證代碼在運(yùn)行時(shí)不會做出什么危害虛擬機(jī)安全的事件;

4.符號引用驗(yàn)證:來驗(yàn)證一些引用的真實(shí)性與可行性,比如代碼里面引了其他類(符號中通過字符串描述的全限定名是否能找到對應(yīng)的類),這里就要去檢測一下那些來究竟是否存在;或者說代碼中訪問了其他類的一些屬性,這里就對那些屬性的可以訪問行進(jìn)行了檢驗(yàn)。(這一步將為后面的解析工作打下基礎(chǔ))

多說兩句。。。 我覺得這個(gè)驗(yàn)證就是看class文件符不符合 jvm 的胃口 , 如果不符合 jvm 的胃口的話,無法完成加載,說明你寫的代碼 有毒.... 偷笑偷笑

3.準(zhǔn)備

準(zhǔn)備階段會為類變量(指的是靜態(tài)變量,這就是我們常說的,靜態(tài)變量/方法 在類加載的時(shí)候就執(zhí)行了,通過類名.靜態(tài)**來調(diào)用)分配內(nèi)存并設(shè)置類的初始值; 值得一提的是 如果有以下語句:

public static int i = 123 ;

在準(zhǔn)備階段的初始值是 0 ,而不是 123 , 是因?yàn)榇藭r(shí) 只是分配內(nèi)存空間而已, 并沒有對 i 進(jìn)行初始化, 真正的對 i 賦值是在 初始化 階段;

4.解析

1.類或接口的解析;

2.字段解析;

3.類方法解析;

4.接口方法解析;

此部分內(nèi)容涉及 invokedynamic指令,靜態(tài)、動(dòng)態(tài)語音調(diào)用 不做展開

如果解析到代碼內(nèi)容有問題,解析不通過將會拋出異常!

5.初始化

類初始化階段是類加載過程中的最后一步,這才是執(zhí)行類中定義的java程序代碼(也可以說是字節(jié)碼)。
在準(zhǔn)備階段,已經(jīng)為變量賦過一次系統(tǒng)要求的初始值,到了初始化階段會根據(jù)程序員的要求出初始化變量賦值。

java虛擬機(jī)沒有嚴(yán)格約束什么時(shí)候開始類加載過程的第一階段,但嚴(yán)格規(guī)定了有且只有5鐘情況必須立即馬上光速對類進(jìn)行 初始化

當(dāng)然加載、驗(yàn)證、準(zhǔn)備需要在次之前,(解析也可以在初始化以后再開始~)

1.遇到new,get static,put static,invoke static這4條字節(jié)碼指令時(shí),假如類還沒進(jìn)行初始化,則馬上對其進(jìn)行初始化工作。
也就是三種情況:用new實(shí)例化一個(gè)對象時(shí)、讀取或設(shè)置一個(gè)雷的靜態(tài)字段時(shí)、執(zhí)行靜態(tài)方法時(shí);

2.使用java.lang.reflect.*的方法對類進(jìn)行反射調(diào)用時(shí),如果類還沒有進(jìn)行過初始化,立即馬上光速對其進(jìn)行初始化!!!

3.初始化一個(gè)類的時(shí)候,如果其父類還沒有被初始化,那么會先去初始化其父類;

4.當(dāng) jvm 啟動(dòng)時(shí),用戶需要指定一個(gè)要執(zhí)行的主類(包含static void main(string 【】args)的那個(gè)類),則jvm會先去初始化這個(gè)類;

5.當(dāng)使用jdk1.7 的動(dòng)態(tài)語言支持時(shí),如果一個(gè)java.lang.invoke.methodhandle實(shí)力最后的解析結(jié)果為 get static,put static,invoke static 的方法句柄,并且這個(gè)方法句柄所對應(yīng)的類沒有進(jìn)行過初始化,則需要先初始化;

小結(jié):

介紹了類加載過程的 加載、驗(yàn)證、準(zhǔn)備、解析、初始化、等5個(gè)階段,以及虛擬機(jī)進(jìn)行了哪些動(dòng)作,簡單敘述了類加載器的工作原理,如果有說得不妥當(dāng)?shù)牡胤剑€以請大家批評指正,多多交流。

原文鏈接:https://blog.csdn.net/world6/article/details/52041857

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 毛片免费看网站 | 激情网站免费观看 | 99国产精成人午夜视频一区二区 | 日韩黄色影视 | av免费在线观看免费 | 黄色三级三级三级 | 欧美人与禽性xxxxx杂性 | 黄色片网站免费在线观看 | 免费看成年人视频在线 | 国产成人av一区二区 | 欧美一区久久久 | 国产精品视频1区 | 超碰一区 | av手机在线电影 | 逼特逼视频在线观看 | 国产免费高清在线视频 | 91亚洲免费视频 | 色综合久久久久久久久久久 | fc2国产成人免费视频 | 久久久久久久久久久av | 欧美h版在线观看 | 午夜伦情电午夜伦情电影 | 一级免费视频 | 高清在线国产 | 国产成人综合在线观看 | 久久国产精品99国产 | 黄色片网站免费观看 | 蜜桃视频日韩 | 国产亚洲精品久久久久婷婷瑜伽 | 成人短视频在线观看免费 | 欧美人的天堂一区二区三区 | 高清一区二区在线观看 | 伊人99re| 一级毛片真人免费播放视频 | 午夜精品福利视频 | 国产精品美女久久久久久不卡 | 五月天堂婷婷 | 亚洲精品久久久久久下一站 | 国产欧美日韩视频在线观看 | 亚洲一区二区在线 | 精品一区二区三区在线视频 |