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

Java中類加載器舉例詳解

 更新時間:2026年01月07日 11:18:10   作者:小白qzx  
Java類加載器是Java語言的核心組件之一,負(fù)責(zé)從文件系統(tǒng)或網(wǎng)絡(luò)中加載Class文件,Class文件在文件開頭有特定的文件標(biāo)識,這篇文章主要介紹了Java中類加載器的相關(guān)資料,需要的朋友可以參考下

類加載器簡介

Java程序被編譯器編譯之后成為字節(jié)碼文件(.class文件),當(dāng)程序需要某個類時,虛擬機(jī)便會將對應(yīng)的class文件進(jìn)行加載,創(chuàng)建出對應(yīng)的Class對象。而這個將class文件加載到虛擬機(jī)內(nèi)存的過程,便是類加載。

類加載器負(fù)責(zé)在運(yùn)行時將Java類動態(tài)加載到JVM(Java虛擬機(jī)),是JRE(Java運(yùn)行時環(huán)境)的一部分。由于類加載器的存在,JVM無需了解底層文件或文件系統(tǒng)即可運(yùn)行Java程序。并且Java類不會一次全部加載到內(nèi)存中,而是在需要時才會加載到內(nèi)存中。

類加載的過程

類的生命周期通常包括:加載、鏈接、初始化、使用和卸載。上圖中包含了類加載的三個階段:加載階段、鏈接階段和初始化階段。如果將這三個階段再拆分細(xì)化包括:加載、驗(yàn)證、準(zhǔn)備、解析和初始化。

這幾個階段的作用簡單概況一下:

  • 加載:通過一個類的完全限定查找類字節(jié)碼文件,轉(zhuǎn)化為方法區(qū)運(yùn)行時的數(shù)據(jù)結(jié)構(gòu),創(chuàng)建一個代表該類的Class對象。
  • 驗(yàn)證:確保Class文件的字節(jié)流中包含信息符合當(dāng)前虛擬機(jī)要求,不會危害虛擬機(jī)自身安全。
  • 準(zhǔn)備:為類變量(即static修飾的字段變量)分配內(nèi)存并且設(shè)置該類變量的初始值。不包含被final修飾的static變量,因?yàn)樗诰幾g時已經(jīng)分配了。
  • 解析:將常量池內(nèi)的符號引用轉(zhuǎn)換為直接引用的過程,比如(main()方法)替換為指向數(shù)據(jù)所存內(nèi)存的指針或句柄等(直接引用),這是所謂的靜態(tài)鏈接過程(類加載期間完成),動態(tài)鏈接是在程序運(yùn)行期間完成的將符號引用替換為直接引用。如果符號引用指向一個未被加載的類,或者未被加載類的字段或方法,那么解析將觸發(fā)這個類的加載。
  • 初始化:類加載最后階段,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化成員變量。對類的靜態(tài)變量初始化為指定的值,執(zhí)行靜態(tài)代碼塊。

在上述類加載的過程中,虛擬機(jī)提供了三種類加載器:啟動(Bootstrap)類加載器、擴(kuò)展(Extension)類加載器、系統(tǒng)(System)類加載器(也稱應(yīng)用類加載器),此外還可以自定義類加載器。

啟動(Bootstrap)類加載器:

系統(tǒng)中最頂層、最核心的加載器,是 JVM 與生俱來的一部分,負(fù)責(zé)加載 JDK 核心類庫,奠定 Java 程序運(yùn)行的基礎(chǔ),由 JVM 的底層代碼(C/C++,如 HotSpot 虛擬機(jī))實(shí)現(xiàn),無法在 Java 代碼中直接獲取其對象(調(diào)用 getClassLoader() 返回 null)。

加載范圍:加載 JDK 核心類庫

  • JDK 8 及之前:加載 <JAVA_HOME>/jre/lib 目錄下的核心 JAR 包(如 rt.jar、charsets.jar、sunrsasign.jar 等),這些 JAR 是 JVM 識別的「核心類庫」(非該目錄下的任意 JAR 不會被加載);
  • JDK 9+(模塊化):移除了 rt.jar 等打包方式,核心類以「模塊」形式存儲在 <JAVA_HOME>/lib/modules(模塊化鏡像文件),啟動類加載器負(fù)責(zé)加載 java.base 等核心模塊(如 java.langjava.io 所屬的模塊)。

擴(kuò)展(Extension)類加載器:

擴(kuò)展類加載器是啟動類加載器的子類,Java語言編寫,由sun.misc.Launcher$ExtClassLoader實(shí)現(xiàn),父類加載器為啟動類加載器,負(fù)責(zé)加載標(biāo)準(zhǔn)核心Java類的擴(kuò)展。

擴(kuò)展類加載器從JDK擴(kuò)展目錄(通常是$JAVA_HOME/lib/ext目錄)或java.ext.dirs系統(tǒng)屬性中指定的任何其他目錄進(jìn)行自動加載。

系統(tǒng)/應(yīng)用(System)類加載器:

系統(tǒng)類加載器負(fù)責(zé)將所有應(yīng)用程序級類加載到JVM中。它加載在類路徑環(huán)境變量,-classpath或-cp命令行選項(xiàng)中找到的文件。它是擴(kuò)展類加載器的子類。

自定義類加載器:

在大多數(shù)情況下,內(nèi)置的三種類加載器就足夠了。但是,在需要從本地硬盤驅(qū)動器或網(wǎng)絡(luò)中加載類的情況下,需要打破雙親委派機(jī)制,則可能需要使用自定義類加載器。

下面介紹類加載器的加載機(jī)制--雙親委派機(jī)制。

雙親委派機(jī)制:

從圖中可以清晰的看到雙親委派機(jī)制的具體過程:加載某個類時會先層層委托給父加載器尋找目標(biāo)類加載,如果父加載器在自己的加載類路徑下都找不到目標(biāo)類,嘗試向下加載。比如我們自己隨便寫的User類,最先會找應(yīng)用程序類加載器加載,應(yīng)用程序類加載器會先委托擴(kuò)展類加載器加載,擴(kuò)展類加載器再委托啟動類加載器,頂層啟動類加載器在自己的類加載路徑里找了半天沒找到User類,則向下退回加載User類的請求,擴(kuò)展類加載器收到回復(fù)就自己加載,在自己的類加載路徑里找了半天也沒找到User類,又向下退回User類的加載請求給應(yīng)用程序類加載器,應(yīng)用程序類加載器于是在自己的類加載路徑里找User類,結(jié)果找到了就自己加載了。雙親委派機(jī)制說簡單點(diǎn)就是,先找父親加載,不行再由兒子自己加載。

我們來看一下loadclass的源碼:

    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                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.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

此方法負(fù)責(zé)加載給定名稱參數(shù)的類。name參數(shù)為類的全限定名。先查找是否已加載該類,若無,則判斷有無父類加載器parent,嘗試給父類加載器去loadclass,其實(shí)就是一個遞歸的順序。

為什么要雙親委派機(jī)制:

沙箱安全機(jī)制:自己寫的java.lang.String.class類不會被加載,這樣便可以防止
核心API庫被隨意篡改( 可以自己寫一個String 類 會發(fā)現(xiàn)報錯 )

避免類的重復(fù)加載:當(dāng)父親已經(jīng)加載了該類時,就沒有必要子ClassLoader再加
載一次,保證被加載類的唯一性

打破雙親委派機(jī)制示例:

1、tomcat:tomcat就是屬于一個web 程序,可能部署倆個應(yīng)用程序,不同的應(yīng)用程序可能會依賴一個第三方類庫的不同版本,不能要求同一個類庫在同一個服務(wù)器只有一份,因此要保證每個應(yīng)用程序的類庫都是獨(dú)立的,保證相互隔離,就需要打破雙親委派機(jī)制。

2、熱部署:熱部署要求 “修改類 / JSP 后,無需重啟應(yīng)用即可生效”,而雙親委派下,類加載器加載類后,該類會被 JVM 緩存,類加載器不銷毀,類就無法重新加載。因此需要自定義類加載器 + 銷毀重建。

總結(jié)

到此這篇關(guān)于Java中類加載器的文章就介紹到這了,更多相關(guān)Java類加載器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringMVC 響應(yīng)數(shù)據(jù)和結(jié)果視圖從環(huán)境搭建到實(shí)戰(zhàn)全解析

    SpringMVC 響應(yīng)數(shù)據(jù)和結(jié)果視圖從環(huán)境搭建到實(shí)戰(zhàn)全解析

    SpringMVC中,Controller方法的返回值決定了響應(yīng)方式,本文詳細(xì)講解了SpringMVC的開發(fā)環(huán)境搭建、Controller方法返回值分類、轉(zhuǎn)發(fā)與重定向機(jī)制,以及JSON異步交互的實(shí)現(xiàn),本文介紹SpringMVC 響應(yīng)數(shù)據(jù)和結(jié)果視圖從環(huán)境搭建到實(shí)戰(zhàn)全解析,感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • Java使用多線程批次查詢大量數(shù)據(jù)(Callable返回?cái)?shù)據(jù))方式

    Java使用多線程批次查詢大量數(shù)據(jù)(Callable返回?cái)?shù)據(jù))方式

    今天給大家分享Java使用多線程批次查詢大量數(shù)據(jù)(Callable返回?cái)?shù)據(jù))方式,多線程有好幾種方式,今天說的方式比較好,實(shí)現(xiàn)Callable<> 這種方式能返回查詢的數(shù)據(jù),加上Future異步獲取方式,查詢效率大大加快,感興趣的朋友一起看看吧
    2023-11-11
  • java開發(fā)使用StringUtils.split避坑詳解

    java開發(fā)使用StringUtils.split避坑詳解

    這篇文章主要為大家介紹了java開發(fā)使用StringUtils.split避坑詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • SpringMVC攔截器詳解

    SpringMVC攔截器詳解

    本篇文章主要介紹了SpringMVC攔截器配置及使用方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-07-07
  • java實(shí)現(xiàn)AES可逆加密算法

    java實(shí)現(xiàn)AES可逆加密算法

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)AES可逆加密算法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • Java獲取漢字拼音的全拼和首拼實(shí)現(xiàn)代碼分享

    Java獲取漢字拼音的全拼和首拼實(shí)現(xiàn)代碼分享

    這篇文章主要介紹了Java獲取漢字拼音的全拼和首拼實(shí)現(xiàn)代碼分享,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-06-06
  • SpringBoot整合RabbitMQ實(shí)現(xiàn)交換機(jī)與隊(duì)列的綁定

    SpringBoot整合RabbitMQ實(shí)現(xiàn)交換機(jī)與隊(duì)列的綁定

    這篇文章將通過幾個實(shí)例為大家介紹一些SpringBoot中RabbitMQ如何綁定交換機(jī)(交換器)與隊(duì)列,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-05-05
  • Java訪問權(quán)限原理與用法詳解

    Java訪問權(quán)限原理與用法詳解

    這篇文章主要介紹了Java訪問權(quán)限,結(jié)合實(shí)例形式詳細(xì)分析了java構(gòu)造者思想、包、訪問修飾符等相關(guān)原理、應(yīng)用與操作注意事項(xiàng),需要的朋友可以參考下
    2020-02-02
  • Java實(shí)現(xiàn)時間戳轉(zhuǎn)代碼運(yùn)行時長

    Java實(shí)現(xiàn)時間戳轉(zhuǎn)代碼運(yùn)行時長

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)時間戳轉(zhuǎn)代碼運(yùn)行時長功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-06-06
  • Java多線程環(huán)境下死鎖模擬

    Java多線程環(huán)境下死鎖模擬

    這篇文章主要介紹了模擬Java多線程環(huán)境下的死鎖,文章介紹一些死鎖的產(chǎn)生條件的相關(guān)資料,具有一定的參考價值,需要的小伙伴可以參考一下,希望對你有所幫助
    2021-12-12

最新評論

金坛市| 塔城市| 二连浩特市| 天全县| 余干县| 日照市| 青铜峡市| 南城县| 揭东县| 永泰县| 稻城县| 三台县| 鹤壁市| 博爱县| 齐河县| 临朐县| 绥江县| 海盐县| 垣曲县| 黄梅县| 塔河县| 淮阳县| 内江市| 祁门县| 黑龙江省| 淳安县| 西宁市| 新密市| 新竹县| 读书| 湖州市| 合山市| 湛江市| 吴忠市| 北辰区| 通许县| 漳平市| 上杭县| 四子王旗| 阳信县| 绥滨县|