Java類加載機(jī)制

類加載機(jī)制

概念

類加載器把class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,存放在方法區(qū),然后在堆區(qū)創(chuàng)建一個(gè)java.lang.Class對(duì)象,用來封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。

1、加載:
查找并加載類的二進(jìn)制數(shù)據(jù)(把class文件里面的信息加載到內(nèi)存里面)

2、連接:
把內(nèi)存中類的二進(jìn)制數(shù)據(jù)合并到虛擬機(jī)的運(yùn)行時(shí)環(huán)境中
(1)驗(yàn)證:確保被加載的類的正確性。包括
A、類文件的結(jié)構(gòu)檢查:檢查是否滿足Java類文件的固定格式
B、語義檢查:確保類本身符合Java的語法規(guī)范
C、字節(jié)碼驗(yàn)證:確保字節(jié)碼流可以被Java虛擬機(jī)安全的執(zhí)行。字節(jié)碼流是操作碼組成的序列。每一個(gè)操作碼后面都會(huì)跟著一個(gè)或者多個(gè)操作數(shù)。字節(jié)碼檢查這個(gè)步驟會(huì)檢查每一個(gè)操作碼是否合法。
D、 二進(jìn)制兼容性驗(yàn)證:確保相互引用的類之間是協(xié)調(diào)一致的。
(2)準(zhǔn)備:為類的靜態(tài)變量分配內(nèi)存,并將其初始化為默認(rèn)值
(3)解析:把類中的符號(hào)引用轉(zhuǎn)化為直接引用(比如說方法的符號(hào)引用,是有方法名和相關(guān)描述符組成,在解析階段,JVM把符號(hào)引用替換成一個(gè)指針,這個(gè)指針就是直接引用,它指向該類的該方法在方法區(qū)中的內(nèi)存位置)

3、初始化:為類的靜態(tài)變量賦予正確的初始值。當(dāng)靜態(tài)變量的等號(hào)右邊的值是一個(gè)常量表達(dá)式時(shí),不會(huì)調(diào)用static代碼塊進(jìn)行初始化。只有等號(hào)右邊的值是一個(gè)運(yùn)行時(shí)運(yùn)算出來的值,才會(huì)調(diào)用static初始化。

雙親委派模型

1、當(dāng)一個(gè)類加載器收到類加載請(qǐng)求的時(shí)候,它首先不會(huì)自己去加載這個(gè)類的信息,而是把該請(qǐng)求轉(zhuǎn)發(fā)給父類加載器,依次向上。所以所有的類加載請(qǐng)求都會(huì)被傳遞到父類加載器中,只有當(dāng)父類加載器中沒有找到所需的類,子類加載器才會(huì)自己嘗試去加載該類。當(dāng)前類加載器和所有父類加載器都無法加載該類時(shí),拋出ClassNotFindException異常。
2、意義:
提高系統(tǒng)的安全性。用戶自定義的類加載器不可能加載應(yīng)該由父加載器加載的可靠類。(比如用戶定義了一個(gè)惡意代碼,自定義的類加載器首先讓系統(tǒng)加載器去加載,系統(tǒng)加載器檢查該代碼不符合規(guī)范,于是就不繼續(xù)加載了)
3、定義類加載器:如果某個(gè)類加載器能夠加載一個(gè)類,那么這個(gè)類加載器就叫做定義類加載器
4、初始類加載器:定義類加載器及其所有子加載器都稱作初始類加載器。
5、運(yùn)行時(shí)包:
(1)由同一個(gè)類加載器加載并且擁有相同包名的類組成運(yùn)行時(shí)包
(2)只有屬于同一個(gè)運(yùn)行時(shí)包的類,才能訪問包可見(default)的類和類成員。作用是 限制用戶自定義的類冒充核心類庫(kù)的類去訪問核心類庫(kù)的包可見成員。
6、加載兩份相同的class對(duì)象的情況:A和B不屬于父子類加載器關(guān)系,并且各自都加載了同一個(gè)類。

特點(diǎn):

1、全盤負(fù)責(zé):當(dāng)一個(gè)類加載器加載一個(gè)類時(shí),該類所依賴的其他類也會(huì)被這個(gè)類加載器加載到內(nèi)存中。
2、緩存機(jī)制:所有的Class對(duì)象都會(huì)被緩存,當(dāng)程序需要使用某個(gè)Class時(shí),類加載器先從緩存中查找,找不到,才從class文件中讀取數(shù)據(jù),轉(zhuǎn)化成Class對(duì)象,存入緩存中。

兩種類型的類加載器

1、 JVM自帶的類加載器(3種):
(1) 根類加載器(Bootstrap):
a、C++編寫的,程序員無法在程序中獲取該類
b、負(fù)責(zé)加載虛擬機(jī)的核心庫(kù),比如java.lang.Object
c、沒有繼承ClassLoader類
(2) 擴(kuò)展類加載器(Extension):
a、Java編寫的,從指定目錄中加載類庫(kù)
b、父加載器是根類加載器
c、是ClassLoader的子類
d、如果用戶把創(chuàng)建的jar文件放到指定目錄中,也會(huì)被擴(kuò)展加載器加載。
(3) 系統(tǒng)加載器(System)或者應(yīng)用加載器(App):
a、Java編寫的
b、父加載器是擴(kuò)展類加載器
c、從環(huán)境變量或者class.path中加載類
d、是用戶自定義類加載的默認(rèn)父加載器
e、是ClassLoader的子類

2、 用戶自定義的類加載器:
(1)Java.lang.ClassLoader類的子類
(2)用戶可以定制類的加載方式
(3)父類加載器是系統(tǒng)加載器
(4)編寫步驟:
A、繼承ClassLoader
B、重寫findClass方法。從特定位置加載class文件,得到字節(jié)數(shù)組,然后利用defineClass把字節(jié)數(shù)組轉(zhuǎn)化為Class對(duì)象
(5)為什么要自定義類加載器?
A、 可以從指定位置加載class文件,比如說從數(shù)據(jù)庫(kù)、云端加載class文件
B、 加密:Java代碼可以被輕易的反編譯,因此,如果需要對(duì)代碼進(jìn)行加密,那么加密以后的代碼,就不能使用Java自帶的ClassLoader來加載這個(gè)類了,需要自定義ClassLoader,對(duì)這個(gè)類進(jìn)行解密,然后加載。

PS

問題:Java程序?qū)︻惖膱?zhí)行有幾種方式:
1、 主動(dòng)使用(6種情況):
// JVM必須在每個(gè)類“首次 主動(dòng)使用”的時(shí)候,才會(huì)初始化這些類。

(1) 創(chuàng)建類的實(shí)例
(2) 讀寫某個(gè)類或者接口的靜態(tài)變量
(3) 調(diào)用類的靜態(tài)方法
(4) 同過反射的API(Class.forName())獲取類
(5) 初始化一個(gè)類的子類
(6) JVM啟動(dòng)的時(shí)候,被標(biāo)明啟動(dòng)類的類(包含Main方法的類)
// 只有當(dāng)程序使用的靜態(tài)變量或者靜態(tài)方法確實(shí)在該類中定義時(shí),該可以認(rèn)為是對(duì)該類或者接口的主動(dòng)使用。
2、 被動(dòng)使用:除了主動(dòng)使用的6種情況,其他情況都是被動(dòng)使用,都不會(huì)導(dǎo)致類的初始化。
3、 JVM規(guī)范允許類加載器在預(yù)料某個(gè)類將要被使用的時(shí)候,就預(yù)先加載它。如果該class文件缺失或者存在錯(cuò)誤,則在程序“首次 主動(dòng)使用”的時(shí)候,才報(bào)告這個(gè)錯(cuò)誤。(Linkage Error錯(cuò)誤)。如果這個(gè)類一直沒有被程序“主動(dòng)使用”,就不會(huì)報(bào)錯(cuò)。

類加載機(jī)制與接口:
1、 當(dāng)Java虛擬機(jī)初始化一個(gè)類時(shí),不會(huì)初始化該類實(shí)現(xiàn)的接口。
2、 在初始化一個(gè)接口時(shí),不會(huì)初始化這個(gè)接口父接口。
3、 只有當(dāng)程序首次使用該接口的靜態(tài)變量時(shí),才導(dǎo)致該接口的初始化。

ClassLoader:
1、 調(diào)用Classloader的loadClass方法去加載一個(gè)類,不是主動(dòng)使用,因此不會(huì)進(jìn)行類的初始化。

類的卸載:
1、 有JVM自帶的三種類加載器(根、擴(kuò)展、系統(tǒng))加載的類始終不會(huì)卸載。因?yàn)镴VM始終引用這些類加載器,這些類加載器使用引用他們所加載的類,因此這些Class類對(duì)象始終是可到達(dá)的。
2、 由用戶自定義類加載器加載的類,是可以被卸載的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容