亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

Java的ClassLoader如何理解

發布時間:2021-11-20 15:04:26 來源:億速云 閱讀:106 作者:柒染 欄目:云計算

本篇文章為大家展示了Java的ClassLoader如何理解,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

講解一下 Java 的 ClassLoader。

關于 ClassLoader ,相信大家用的不是很多,但是在面試中可能會被經常問到。所以我這里整理了關于它的一些相關用法。

ClassLoader 是 Java 提供的類加載器,用來加載 Java 類到 Java 虛擬機中的一種加載器。

Java 程序(class文件)并不是本地的可執行程序。當運行Java程序時,首先運行JVM(Java虛擬機),然后再把Java class加載到JVM里頭運行,負責加載Java class的這部分就叫做Class Loader。

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

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

了解了上面的流程后,我們再通過具體的代碼來看看類是如何被加載的。

1

2

3

4

5

6

7

8

9

package com.neo.classloader;

public class ClassLoaderTest {

     public static void main(String[] args) {

        ClassLoader loader = Thread.currentThread().getContextClassLoader();

        System.out.println(loader);

        System.out.println(loader.getParent());

        System.out.println(loader.getParent().getParent());

    }

}

運行后,輸出結果:

1

2

3

sun.misc.Launcher$AppClassLoader@64fef26a

sun.misc.Launcher$ExtClassLoader@1ddd40f3

null

從上面的結果可以看出,并沒有獲取到 ExtClassLoader 的父 Loader,原因是 Bootstrap Loader(引導類加載器)是用C語言實現的,找不到一個確定的返回父 Loader 的方式,于是就返回 null。 這幾種類加載器的層次關系如下圖所示:

Java的ClassLoader如何理解

注意:這里父類加載器并不是通過繼承關系來實現的,而是采用組合實現的。

站在Java虛擬機的角度來講,只存在兩種不同的類加載器:啟動類加載器:它使用C++實現(這里僅限于Hotspot,也就是JDK1.5之后默認的虛擬機,有很多其他的虛擬機是用Java語言實現的),是虛擬機自身的一部分;所有其它的類加載器:這些類加載器都由Java語言實現,獨立于虛擬機之外,并且全部繼承自抽象類java.lang.ClassLoader,這些類加載器需要由啟動類加載器加載到內存中之后才能去加載其他的類。

站在Java開發人員的角度來看,類加載器可以大致劃分為以下三類:

啟動類加載器Bootstrap ClassLoader,負責加載存放在JDK\jre\lib(JDK代表JDK的安裝目錄,下同)下,或被-Xbootclasspath參數指定的路徑中的,并且能被虛擬機識別的類庫(如rt.jar,所有的java.開頭的類均被Bootstrap ClassLoader加載)。啟動類加載器是無法被Java程序直接引用的。
擴展類加載器Extension ClassLoader,該加載器由sun.misc.Launcher$ExtClassLoader實現,它負責加載JDK\jre\lib\ext目錄中,或者由java.ext.dirs系統變量指定的路徑中的所有類庫(如javax.
開頭的類),開發者可以直接使用擴展類加載器。
應用程序類加載器Application ClassLoader,該類加載器由sun.misc.Launcher$AppClassLoader來實現,它負責加載用戶類路徑(ClassPath)所指定的類,開發者可以直接使用該類加載器,如果應用程序中沒有自定義過自己的類加載器,一般情況下這個就是程序中默認的類加載器。

應用程序都是由這三種類加載器互相配合進行加載的,如果有必要,我們還可以加入自定義的類加載器。因為JVM自帶的ClassLoader只是懂得從本地文件系統加載標準的java class文件,因此如果編寫了自己的ClassLoader,便可以做到如下幾點:

  • 1、在執行非置信代碼之前,自動驗證數字簽名。

  • 2、動態地創建符合用戶特定需要的定制化構建類。

  • 3、從特定的場所取得java class,例如數據庫中和網絡中。

JVM類加載機制

  • 全盤負責,當一個類加載器負責加載某個Class時,該Class所依賴的和引用的其他Class也將由該類加載器負責載入,除非顯示使用另外一個類加載器來載入

  • 父類委托,先讓父類加載器試圖加載該類,只有在父類加載器無法加載該類時才嘗試從自己的類路徑中加載該類

  • 緩存機制,緩存機制將會保證所有加載過的Class都會被緩存,當程序中需要使用某個Class時,類加載器先從緩存區尋找該Class,只有緩存區不存在,系統才會讀取該類對應的二進制數據,并將其轉換成Class對象,存入緩存區。這就是為什么修改了Class后,必須重啟JVM,程序的修改才會生效

類加載有三種方式:

  • 1、命令行啟動應用時候由JVM初始化加載

  • 2、通過Class.forName()方法動態加載

  • 3、通過ClassLoader.loadClass()方法動態加載

例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

package com.xttblog.classloader;

public class loaderTest {

        public static void main(String[] args) throws ClassNotFoundException {

            ClassLoader loader = HelloWorld.class.getClassLoader();

            System.out.println(loader);

            loader.loadClass("Test2");

        }

}

Test2.java

1

2

3

4

5

public class Test2 {

    static {

        System.out.println("靜態初始化塊執行了!");

    }

}

分別切換加載方式,會有不同的輸出結果。

Class.forName()和ClassLoader.loadClass()區別

  • Class.forName():將類的.class文件加載到jvm中之外,還會對類進行解釋,執行類中的static塊;

  • ClassLoader.loadClass():只干一件事情,就是將.class文件加載到jvm中,不會執行static中的內容,只有在newInstance才會去執行static塊。

  • Class.forName(name, initialize, loader)帶參函數也可控制是否加載static塊。并且只有調用了newInstance()方法采用調用構造函數,創建類的對象 。

總結:Java 類的加載機制和ClassLoader看似復雜,實際上卻很簡單。通過閱讀源碼或結合運行示例就能更好的理解了。

上述內容就是Java的ClassLoader如何理解,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

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

AI

驻马店市| 油尖旺区| 武邑县| 鄱阳县| 双流县| 乌恰县| 巴林左旗| 安图县| 棋牌| 九寨沟县| 星子县| 和平区| 宝兴县| 长汀县| 从江县| 丰台区| 宣恩县| 临洮县| 黎川县| 中江县| 礼泉县| 安达市| 建阳市| 四平市| 丰城市| 绥宁县| 六盘水市| 昂仁县| 元朗区| 凤山市| 巴里| 大城县| 霍城县| 格尔木市| 桃园市| 玉林市| 保康县| 平泉县| 塔城市| 新邵县| 开原市|