溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

classloader類加載器基于java類的加載方式的示例分析

發(fā)布時間:2021-08-19 15:04:06 來源:億速云 閱讀:229 作者:小新 欄目:編程語言

這篇文章主要介紹classloader類加載器基于java類的加載方式的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

基礎(chǔ)概念

Classloader 類加載器,用來加載 Java 類到 Java 虛擬機中。與普通程序不同的是。Java程序(class文件)并不是本地的可執(zhí)行程序。當運行Java程序時,首先運行JVM(Java虛擬機),然后再把Java class加載到JVM里頭運行,負責加載Java class的這部分就叫做Class Loader。

JVM本身包含了一個ClassLoader稱為Bootstrap ClassLoader,和JVM一樣,BootstrapClassLoader是用本地代碼實現(xiàn)的,它負責加載核心JavaClass(即所有java.*開頭的類)。另外JVM還會提供兩個ClassLoader,它們都是用Java語言編寫的,由BootstrapClassLoader加載;其中Extension ClassLoader負責加載擴展的Javaclass(例如所有javax.*開頭的類和存放在JRE的ext目錄下的類),ApplicationClassLoader負責加載應用程序自身的類。

當運行一個程序的時候,JVM啟動,運行bootstrapclassloader,該ClassLoader加載java核心API(ExtClassLoader和AppClassLoader也在此時被加載),然后調(diào)用ExtClassLoader加載擴展API,最后AppClassLoader加載CLASSPATH目錄下定義的Class,這就是一個程序最基本的加載流程。

注: 學ClassLoader看OSGI程序應用

什么時候JVM會使用ClassLoader加載一個類呢?當你使用java去執(zhí)行一個類,JVM使用ApplicationClassLoader加載這個類;然后如果類A引用了類B,不管是直接引用還是用Class.forName()引用,JVM就會找到加載類A的ClassLoader,并用這個ClassLoader來加載類B。JVM按照運行時的有效執(zhí)行語句,來決定是否需要裝載新類,從而裝載盡可能少的類,這一點和編譯類是不相同的。

Why use your own ClassLoader?

似乎JVM自身的ClassLoader已經(jīng)足夠了,為什么我們還需要創(chuàng)建自己的ClassLoader呢?

因為JVM自帶的ClassLoader只是懂得從本地文件系統(tǒng)加載標準的java class文件,如果編寫你自己的ClassLoader,你可以做到:

1)在執(zhí)行非置信代碼之前,自動驗證數(shù)字簽名

2)動態(tài)地創(chuàng)建符合用戶特定需要的定制化構(gòu)建類

3)從特定的場所取得java class,例如數(shù)據(jù)庫中

4) 等等

事實上當使用Applet的時候,就用到了特定的ClassLoader,因為這時需要從網(wǎng)絡(luò)上加載java class,并且要檢查相關(guān)的安全信息。

應用服務器大都使用了ClassLoader技術(shù),即使你不需要創(chuàng)建自己的ClassLoader,了解其原理也有助于更好地部署自己的應用。

重點注明:其實一個已經(jīng)加載的類是無法被更新的,如果你試圖用同一個ClassLoader再次加載同一個類,就會得到異常(java.lang.LinkageError: duplicate classdefinition),我們只能夠重新創(chuàng)建一個新的ClassLoader實例來再次加載新類。至于原來已經(jīng)加載的類,開發(fā)人員不必去管它,因為它可能還有實例正在被使用,只要相關(guān)的實例都被內(nèi)存回收了,那么JVM就會在適當?shù)臅r候把不會再使用的類卸載。

絕大部分Java程序都會使用3種系統(tǒng)提供的類加載器

1.啟動類加載器(Bootstrap ClassLoader),負責將存在<JAVA_HOME>\lib目錄中的,或被-Xbootclasspath參數(shù)所指定的路徑中的,并且是虛擬機識別的類庫加載到虛擬機里.注意是按照文件名識別,如rt.jar,名字不符合的類庫即使放在lib目錄中也不會被加載。

2.擴展類加載器(ExtClassLoader),它負責<JAVA_HOME>\lib\ext目錄中的,或被java.ext.dirs系統(tǒng)變量所指定的路徑中的所有類庫.

3.應用程序類加載器(App-ClassLoader),通過cassLoader.getSystemClassLoader()獲取,它負責加載用戶類路徑(ClassPath)上所指定的類庫,一般情況下這個是程序中默認的類加載器.

雙親委托模式 是Java設(shè)計者推薦給開發(fā)者的一種類加載實現(xiàn)方式.雙親委托模型的工作過程是:如果一個類加載器收到了類加載請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成.每一層次的類加載器都是如此,因此所有的加載請求最終都會傳送到頂層的啟動類加載器中,只有當父類加載器沒有找到所需的類時,子加載器才會嘗試自己去加載。雙親模式的好處是Java類隨著它的類加載器一起具備了一種帶優(yōu)先級的層次關(guān)系。例如類Object,存放在rt.jar中,無論哪個類加載器加載這個類,最終都是委派給處于模型最頂端的啟動類加載,因此Object類在程序使用多種類加載器環(huán)境中依然能保證是同一個類。相反,如果沒有使用雙親模型,就可能出現(xiàn)用戶自己編寫一個Object類,導致系統(tǒng)中出現(xiàn)多個不同的Object類,這樣Java類型體系中最基礎(chǔ)的行為也就無法保證。

以上是“classloader類加載器基于java類的加載方式的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI