欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的ClassLoader類加載器使用詳解

 更新時(shí)間:2023年10月07日 09:26:47   作者:cloneme01  
這篇文章主要介紹了Java中的ClassLoader類加載器使用詳解,ClassLoader用于將CLASS文件動(dòng)態(tài)加載到JVM中去,是所有類加載器的基類,所有繼承自抽象的ClassLoader的加載器,都會(huì)優(yōu)先判斷是否被父類加載器加載過,防止多次加載,需要的朋友可以參考下

1. CLASSLOADER是什么

ClassLoader,類加載器。用于將CLASS文件動(dòng)態(tài)加載到JVM中去,是所有類加載器的基類(Bootstrap ClassLoader不繼承自ClassLoader),所有繼承自抽象的ClassLoader的加載器,都會(huì)優(yōu)先判斷是否被父類加載器加載過,防止多次加載。

官網(wǎng)的JVM:https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf

(1)定義:

把“類加載階段”中的「通過一個(gè)類的全限定名來獲取描述此類的二進(jìn)制字節(jié)流」這個(gè)動(dòng)作放到JAVA虛擬機(jī)外部去實(shí)現(xiàn),以便讓應(yīng)用程序自己決定如何去獲取所需要的類。

實(shí)現(xiàn)這個(gè)動(dòng)作的代碼模塊稱為「類加載器」。

(2)作用:

CLASSLOADER的作用就是將CLASS文件讀入內(nèi)存中,并為之生成對(duì)應(yīng)的java.lang.Class對(duì)象。

2. 三個(gè)默認(rèn)CLASSLOADER

①. BootStrap ClassLoader : 啟動(dòng)類加載器,在JVM啟動(dòng)時(shí)創(chuàng)建,用于加載JAVA核心類庫(kù)。它是JVM的一部分,主要加載JVM自身工作所需要的類。

②. Extension ClassLoader : 擴(kuò)展類加載器,加載目錄%JRE_HOME%\lib\ext目錄下的JAR包和CLASS文件。

③. Application ClassLoader : 應(yīng)用程序類加載器,加載應(yīng)用程序CLASSPATH目錄下的所有JAR包和CLASS文件。

在這里插入圖片描述

3. 默認(rèn)CLASSLOADER的關(guān)系

(1) 加載關(guān)系

①. ExtentionClassLoader的父加載器是BootstrapClassLoader。 ②. AppclassLoader的父加載器是ExtentionClassLoader。

(2) 繼承關(guān)系

①. ExtentionClassLoader對(duì)應(yīng)的是ExtClassLoader.java,是在sun.misc.Launcher類中作為一個(gè)內(nèi)部類的,父類是java.net.URLClassLoader;

②. AppclassLoader對(duì)應(yīng)的是AppClassLoader.java,也是在sun.misc.Launcher類中作為一個(gè)內(nèi)部類的,父類也是java.net.URLClassLoader;

③. BootstrapClassLoader是C++編寫的,沒有對(duì)應(yīng)的java類,所以也成不了父類。

(3) 檢查順序和加載順序

AppClassLoader和ExtClassLoader是Launcher的靜態(tài)內(nèi)部類,在程序啟動(dòng)時(shí)JVM會(huì)創(chuàng)建Launcher對(duì)象,Launcher構(gòu)造器會(huì)同時(shí)會(huì)創(chuàng)建擴(kuò)展類加載器和應(yīng)用類加載器。

①. 加載過程中會(huì)先檢查類是否被已加載,檢查順序是自底向上,從User ClassLoader到BootStrap ClassLoader逐層檢查,只要某個(gè)CLASSLOADER已加載過此類,就視為此類已被加載,保證此類在所有CLASSLOADER中只被加載一次;加載順序是自頂向下,從BootStrap ClassLoader到User ClassLoader逐層嘗試加載此類;

②. 在加載類時(shí),每個(gè)類加載器都會(huì)將加載任務(wù)上交給其父類,如果其父類找不到,再由自己去加載;

③. Bootstrap Loader(啟動(dòng)類加載器)是最頂級(jí)的類加載器了,其父加載器為NULL。

4. 自定義CLASSLOADER

如果我們自定義一個(gè)加載器,一般繼承自java.lang.ClassLoader類,或者繼承他的子類,比如:java.net.URLClassLoader,此時(shí)默認(rèn)的父加載器是AppClassLoader。具體步驟如下:

①. 編寫一個(gè)繼承自 java.lang.ClassLoader 或者 java.net.URLClassLoader 的類;

②. 重寫findClass()方法或者重寫loadClass()方法;

③. 在findClass()中使用defineClass()方法,這個(gè)方法是父類ClassLoader中的方法。

// 定義一個(gè)JAVA類
public class Hello {
    public String say() {
        System.out.println("HELLO WORLD!");
        return "OK";
    }
}
// 自定義類加載器
public class MyClassLoader extends ClassLoader {
    private String path;
    MyClassLoader(String path) {
        this.path = path;
    }
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            File file = new File(this.path.concat(name).concat(".class"));
            FileInputStream in = new FileInputStream(file);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int length = -1;
            while ((length = in.read(bytes)) != -1) {
                out.write(bytes, 0, length);
            }
            return defineClass(name, bytes, 0, bytes.length);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return super.findClass(name);
    }
}
// 調(diào)用測(cè)試
public class T {
    public static void main(String[] args) throws Exception {
        String path = Hello.class.getClassLoader().getResource("org/apache/atlas/util/").getPath();
        MyClassLoader my = new MyClassLoader(path);
        // 注意需要帶上包路徑
        Class<?> cls = my.loadClass("org.apache.atlas.util.Hello");
        Object hello = cls.newInstance();
        Method method = cls.getMethod("say", null);
        method.invoke(hello);
    }
}

5. 使用自定義的CLASSLOADER是否可以熱加載CLASS?

①. JAVA目前沒有專門的API,來卸載JVM中已加載的類;

②. 要卸載JVM中的類,需要該類的對(duì)象都被回收,加載該類的ClassLoader也被回收,使用該類的線程結(jié)束等條件;

③. 但是,在JAVA中不同的ClassLoader實(shí)例可以加載同一個(gè)類,即使CLASS文件是同一個(gè)也可以被加載。但是同一個(gè)ClassLoader實(shí)例不能重復(fù)加載同一個(gè)類;

④. 綜上, 雖然可以熱加載CLASS,但是在不停服務(wù)的情況下熱替換CLASS不是很建議,雖然可以通過新建CLASSLOADER實(shí)例的方法來改變新加載的CLASS的內(nèi)容,但之前CLASSLOADER加載的類和對(duì)象并不會(huì)被修改,什么時(shí)候能被GC回收不可控。

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

相關(guān)文章

  • 詳解記錄Java Log的幾種方式

    詳解記錄Java Log的幾種方式

    很多小伙伴不知道如何記錄日志,今天特地整理了本篇文章,文中有非常詳細(xì)的介紹及代碼示例,對(duì)小伙伴們很有幫助,需要的朋友可以參考下
    2021-06-06
  • SpringBoot @PathVariable使用時(shí)遇到的問題及解決

    SpringBoot @PathVariable使用時(shí)遇到的問題及解決

    這篇文章主要介紹了SpringBoot @PathVariable使用時(shí)遇到的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java函數(shù)式編程(三):列表的轉(zhuǎn)化

    Java函數(shù)式編程(三):列表的轉(zhuǎn)化

    這篇文章主要介紹了Java函數(shù)式編程(二):列表的轉(zhuǎn)化,lambda表達(dá)式不僅能幫助我們遍歷集合,并且可以進(jìn)行集合的轉(zhuǎn)化,需要的朋友可以參考下
    2014-09-09
  • Spring通過<import>標(biāo)簽導(dǎo)入外部配置文件

    Spring通過<import>標(biāo)簽導(dǎo)入外部配置文件

    之前文章里我們講到Spring加載Xml配置文件的細(xì)節(jié),那么加載完了我們肯定要解析這個(gè)配置文件中定義的元素。這篇我們首先來分析下Spring是如何通過標(biāo)簽導(dǎo)入外部配置文件的。
    2021-06-06
  • SpringBoot+MyBatisPlus+MySQL8實(shí)現(xiàn)樹形結(jié)構(gòu)查詢

    SpringBoot+MyBatisPlus+MySQL8實(shí)現(xiàn)樹形結(jié)構(gòu)查詢

    這篇文章主要為大家詳細(xì)介紹了SpringBoot+MyBatisPlus+MySQL8實(shí)現(xiàn)樹形結(jié)構(gòu)查詢,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 解決rror updating database.Cause:java.sql.SQLSyntaxErrorException問題

    解決rror updating database.Cause:java.sql.SQLSyntaxE

    這篇文章主要介紹了解決rror updating database.Cause:java.sql.SQLSyntaxErrorException問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Maven的常用命令總結(jié)大全

    Maven的常用命令總結(jié)大全

    這篇文章主要給大家介紹了Maven常用命令總結(jié)的相關(guān)資料,maven最大的作用就是用于對(duì)項(xiàng)目中jar包依賴的統(tǒng)一管理,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • JAVA中阻止類的繼承(官方和非官方)

    JAVA中阻止類的繼承(官方和非官方)

    在面向?qū)ο蟮睦碚撝? 有一些方案要求你用一個(gè)辦法來聲明一個(gè)不可繼承的類。一般而言,如果類提供的功能不應(yīng)該被改變,或者更恰當(dāng)?shù)恼f,是被覆蓋(override)的時(shí)候才會(huì)出現(xiàn)這種情況。在這篇文章里,我討論在JAVA語(yǔ)言中的實(shí)現(xiàn)辦法--官方和非官方的辦法
    2014-01-01
  • java實(shí)現(xiàn)猜數(shù)字小游戲

    java實(shí)現(xiàn)猜數(shù)字小游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)猜數(shù)字小游戲,隨機(jī)給定一個(gè)數(shù)字,直到猜對(duì)大小,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 用Java實(shí)現(xiàn)春聯(lián)?支持自定義字體顏色

    用Java實(shí)現(xiàn)春聯(lián)?支持自定義字體顏色

    大家好,本篇文章主要講的是用Java編寫春聯(lián)?支持自定義字體顏色,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01

最新評(píng)論