溫馨提示×

溫馨提示×

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

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

Java的雙親委派模型是什么

發(fā)布時間:2022-01-06 16:37:46 來源:億速云 閱讀:150 作者:iii 欄目:云計算

這篇文章主要講解了“Java的雙親委派模型是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Java的雙親委派模型是什么”吧!

雙親委派模型的工作流程是:如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把請求委托給父加載器去完成,依次向上,因此,所有的類加載請求最終都應(yīng)該被傳遞到頂層的啟動類加載器中,只有當(dāng)父加載器在它的搜索范圍中沒有找到所需的類時,即無法完成該加載,子加載器才會嘗試自己去加載該類。

雙親委派機制:

  • 1、當(dāng)AppClassLoader加載一個class時,它首先不會自己去嘗試加載這個類,而是把類加載請求委派給父類加載器ExtClassLoader去完成。

  • 2、當(dāng)ExtClassLoader加載一個class時,它首先也不會自己去嘗試加載這個類,而是把類加載請求委派給BootStrapClassLoader“`去完成。

  • 3、如果BootStrapClassLoader加載失敗(例如在$JAVA_HOME/jre/lib里未查找到該class),會使用ExtClassLoader來嘗試加載;

  • 4、若ExtClassLoader也加載失敗,則會使用AppClassLoader來加載,如果AppClassLoader也加載失敗,則會報出異常ClassNotFoundException

ClassLoader源碼分析:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

public Class<?> loadClass(String name)throws ClassNotFoundException {

        return loadClass(name, false);

}

protected synchronized Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException {

    Class c = findLoadedClass(name);

    if (c == null) {

        try {

            if (parent != null) {

                c = parent.loadClass(name, false);

            } else {

                c = findBootstrapClass0(name);

            }

        } catch (ClassNotFoundException e) {

            c = findClass(name);

        }

    }

    if (resolve) {

        resolveClass(c);

    }

    return c;

}

雙親委派模型意義:

  • 系統(tǒng)類防止內(nèi)存中出現(xiàn)多份同樣的字節(jié)碼

  • 保證Java程序安全穩(wěn)定運行

什么是雙親委派模型?

簡單說,類加載器就是根據(jù)指定全限定名稱將class文件加載到JVM內(nèi)存,轉(zhuǎn)為Class對象。如果站在JVM的角度來看,只存在兩種類加載器:

  • 啟動類加載器(Bootstrap ClassLoader):由C++語言實現(xiàn)(針對HotSpot),負責(zé)將存放在<JAVA_HOME>\lib目錄或-Xbootclasspath參數(shù)指定的路徑中的類庫加載到內(nèi)存中。

  • 其他類加載器:由Java語言實現(xiàn),繼承自抽象類ClassLoader。如:擴展類加載器(Extension ClassLoader):負責(zé)加載<JAVA_HOME>\lib\ext目錄或java.ext.dirs系統(tǒng)變量指定的路徑中的所有類庫。應(yīng)用程序類加載器(Application ClassLoader)。負責(zé)加載用戶類路徑(classpath)上的指定類庫,我們可以直接使用這個類加載器。一般情況,如果我們沒有自定義類加載器默認就是用這個加載器。

雙親委派模型工作過程

雙親委派模型工作過程是:如果一個類加載器收到類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器完成。每個類加載器都是如此,只有當(dāng)父加載器在自己的搜索范圍內(nèi)找不到指定的類時(即ClassNotFoundException),子加載器才會嘗試自己去加載。

Java的雙親委派模型是什么

為什么需要雙親委派模型?

為什么需要雙親委派模型呢?假設(shè)沒有雙親委派模型,試想一個場景:

黑客自定義一個java.lang.String類,該String類具有系統(tǒng)的String類一樣的功能,只是在某個函數(shù)稍作修改。比如equals函數(shù),這個函數(shù)經(jīng)常使用,如果在這這個函數(shù)中,黑客加入一些“病毒代碼”。并且通過自定義類加載器加入到JVM中。此時,如果沒有雙親委派模型,那么JVM就可能誤以為黑客自定義的java.lang.String類是系統(tǒng)的String類,導(dǎo)致“病毒代碼”被執(zhí)行。

而有了雙親委派模型,黑客自定義的java.lang.String類永遠都不會被加載進內(nèi)存。因為首先是最頂端的類加載器加載系統(tǒng)的java.lang.String類,最終自定義的類加載器無法加載java.lang.String類。

或許你會想,我在自定義的類加載器里面強制加載自定義的java.lang.String類,不去通過調(diào)用父加載器不就好了嗎?確實,這樣是可行。但是,在JVM中,判斷一個對象是否是某個類型時,如果該對象的實際類型與待比較的類型的類加載器不同,那么會返回false。

舉個簡單例子:

ClassLoader1、ClassLoader2都加載java.lang.String類,對應(yīng)Class1、Class2對象。那么Class1對象不屬于ClassLoad2對象加載的java.lang.String類型。

感謝各位的閱讀,以上就是“Java的雙親委派模型是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Java的雙親委派模型是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責(zé)聲明:本站發(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