最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的ClassLoader雙親委派機制詳解

 更新時間:2025年05月16日 17:25:04   作者:二六八  
這篇文章主要介紹了Java中的ClassLoader雙親委派機制,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

Java ClassLoader雙親委派機制

什么是雙親委派模型

“類加載體系”及ClassLoader雙親委派機制。java程序中的 .java文件編譯完會生成 .class文件,而 .class文件就是通過被稱為類加載器的ClassLoader加載的,而ClassLoder在加載過程中會使用“雙親委派機制”來加載 .class文件。

  1. BootStrapClassLoader:啟動類加載器,該ClassLoader是jvm在啟動時創(chuàng)建的,用于加載 $JAVA_HOME/jre/lib下面的類庫(或者通過參數(shù)-Xbootclasspath指定)。由于引導類加載器涉及到虛擬機本地實現(xiàn)細節(jié),開發(fā)者無法直接獲取到啟動類加載器的引用,所以不能直接通過引用進行操作(由c++編寫)。
  2. ExtClassLoader:擴展類加載器,該ClassLoader是在sun.misc.Launcher里作為一個內(nèi)部類ExtClassLoader定義的(即 sun.misc.Launcher$ExtClassLoader),ExtClassLoader會加載 $JAVA_HOME/jre/lib/ext下的類庫(或者通過參數(shù)-Djava.ext.dirs指定)。
  3. AppClassLoader:應用程序類加載器,該ClassLoader同樣是在sun.misc.Launcher里作為一個內(nèi)部類AppClassLoader定義的(即 sun.misc.Launcher$AppClassLoader),AppClassLoader會加載java環(huán)境變量CLASSPATH所指定的路徑下的類庫,而CLASSPATH所指定的路徑可以通過System.getProperty(“java.class.path”)獲??;當然,該變量也可以覆蓋,可以使用參數(shù)-cp,例如:java -cp 路徑 (可以指定要執(zhí)行的class目錄)。
  4. CustomClassLoader:自定義類加載器,該ClassLoader是指我們自定義的ClassLoader,比如tomcat的StandardClassLoader屬于這一類;當然,大部分情況下使用AppClassLoader就足夠了。

ClassLoader的loadClass(String name, boolean resolve)源碼:

protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        // First, check if the class has already been loaded
        Class c = findLoadedClass(name);
        if (c == null) {
            try {
                if (parent != null) {
                    c = parent.loadClass(name, false);
                } else {
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
                // ClassNotFoundException thrown if class not found
                // from the non-null parent class loader
            }
            if (c == null) {
                // If still not found, then invoke findClass in order
                // to find the class.
                c = findClass(name);
            }
        }
        if (resolve) {
            resolveClass(c);
        }
        return c;
    }

代碼很明朗:

首先找緩存(findLoadedClass),沒有的話就判斷有沒有parent,有的話就用parent來遞歸的loadClass,然而ExtClassLoader并沒有設(shè)置parent,則會通過findBootstrapClassOrNull來加載class,而findBootstrapClassOrNull則會通過JNI方法

private native Class findBootstrapClass(String name) 

來使用BootStrapClassLoader來加載class。

然后如果parent未找到class,則會調(diào)用findClass來加載class,findClass是一個protected的空方法,可以覆蓋它以便自定義class加載過程。

另外,雖然ClassLoader加載類是使用loadClass方法,但是鼓勵用 ClassLoader 的子類重寫 findClass(String),而不是重寫loadClass,這樣就不會覆蓋了類加載默認的雙親委派機制。

雙親委派機制為什么安全

舉個例子,ClassLoader加載的class文件來源很多,比如編譯器編譯生成的class、或者網(wǎng)絡(luò)下載的字節(jié)碼。而一些來源的class文件是不可靠的,比如我可以自定義一個java.lang.Integer類來覆蓋jdk中默認的Integer類,

例如下面這樣:

package java.lang;

public class Integer {
    public Integer(int value) {
        System.exit(0);
    }
}

初始化這個Integer的構(gòu)造器是會退出JVM,破壞應用程序的正常進行,如果使用雙親委派機制的話該Integer類永遠不會被調(diào)用,因為委托BootStrapClassLoader加載后會加載JDK中的Integer類而不會加載自定義的這個,可以看下下面這測試個用例:

public static void main(String... args) {
        Integer i = new Integer(1);
        System.err.println(i);
    }

執(zhí)行時JVM并未在new Integer(1)時退出,說明未使用自定義的Integer,于是就保證了安全性。

為什么需要雙親委派模型

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

黑客自定義一個java.lang.String類,該String類具有系統(tǒng)的String類一樣的功能,只是在某個函數(shù)稍作修改。比如equals函數(shù),這個函數(shù)經(jīng)常使用,如果在這這個函數(shù)中,黑客加入一些“病毒代碼”。并且通過自定義類加載器加入到JVM中。此時,如果沒有雙親委派模型,那么JVM就可能誤以為黑客自定義的java.lang.String類是系統(tǒng)的String類,導致“病毒代碼”被執(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類,對應Class1、Class2對象。
  • 那么Class1對象不屬于ClassLoad2對象加載的java.lang.String類型。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java數(shù)組排序示例(冒泡排序、快速排序、希爾排序、選擇排序)

    java數(shù)組排序示例(冒泡排序、快速排序、希爾排序、選擇排序)

    java中在運用數(shù)組進行排序功能時,一般有四種方法:快速排序法、冒泡法、選擇排序法、插入排序法(希爾排序(Shell Sort)是插入排序的一種),下面是一些示例,需要的朋友可以參考下
    2014-03-03
  • Java基礎(chǔ)之包裝類

    Java基礎(chǔ)之包裝類

    這篇文章主要介紹了Java基礎(chǔ)之包裝類,文中有非常詳細的代碼示例及基礎(chǔ)知識詳解,對正在學習java基礎(chǔ)的小伙伴們有很大的幫助喲,需要的朋友可以參考下
    2021-05-05
  • Java中的@PostConstruct注解的使用

    Java中的@PostConstruct注解的使用

    本文主要介紹了Java中的@PostConstruct注解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • 一文秒懂?kafka?HA(高可用)

    一文秒懂?kafka?HA(高可用)

    這篇文章主要介紹了秒懂?kafka?HA(高可用)的相關(guān)知識,本文我們來說一說和?kafka?高可用相關(guān)的一些策略,對kafka?HA相關(guān)知識感興趣的朋友一起看看吧
    2021-11-11
  • Oracle+Mybatis的foreach insert批量插入報錯的快速解決辦法

    Oracle+Mybatis的foreach insert批量插入報錯的快速解決辦法

    本文給大家介紹Oracle+Mybatis的foreach insert批量插入報錯的快速解決辦法,非常不錯,具有參考借鑒價值,感興趣的朋友參考下吧
    2016-08-08
  • java實現(xiàn)2048游戲源代碼

    java實現(xiàn)2048游戲源代碼

    這篇文章主要為大家詳細介紹了java實現(xiàn)2048游戲源代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • JavaSE-面向?qū)ο?方法重寫)

    JavaSE-面向?qū)ο?方法重寫)

    子類在調(diào)用父類的私有方法中不能直接調(diào)用,但是可以通過get方法進行調(diào)用,修改屬性的值可以通過set方法進行修改。而子類想要修改父類中的方法可以使用方法重寫進行操作。
    2021-08-08
  • JAVASE系統(tǒng)實現(xiàn)抽卡功能

    JAVASE系統(tǒng)實現(xiàn)抽卡功能

    這篇文章主要為大家詳細介紹了JAVASE系統(tǒng)實現(xiàn)抽卡功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Java中實現(xiàn)可拖放圖片剪裁入門教程

    Java中實現(xiàn)可拖放圖片剪裁入門教程

    這篇文章主要介紹了Java中實現(xiàn)可拖放圖片剪裁入門教程,本文寫給新手,分步驟講解如何實現(xiàn)圖片裁剪,并對每步的代碼作注釋,需要的朋友可以參考下
    2015-01-01
  • Java 十大排序算法之計數(shù)排序刨析

    Java 十大排序算法之計數(shù)排序刨析

    計數(shù)排序是一個非基于比較的排序算法,該算法于1954年由 Harold H. Seward 提出。它的優(yōu)勢在于在對一定范圍內(nèi)的整數(shù)排序時,它的復雜度為Ο(n+k)(其中k是整數(shù)的范圍),快于任何比較排序算法
    2021-11-11

最新評論

红原县| 阿拉善右旗| 吉安市| 泸溪县| 萨迦县| 苗栗市| 云林县| 云南省| 上饶市| 岚皋县| 台南市| 安新县| 徐州市| 敖汉旗| 会同县| 班玛县| 湖南省| 弥勒县| 武陟县| 田阳县| 鲜城| 西充县| 城固县| 营山县| 东光县| 芦山县| 霸州市| 双鸭山市| 巨鹿县| 龙江县| 乐清市| 张家界市| 银川市| 周口市| 中西区| 呼伦贝尔市| 汶上县| 商水县| 泸定县| 新兴县| 拉萨市|