Java——》类加载器ClassLoader

38 篇文章 3 订阅

推荐链接:
    总结——》【Java】
    总结——》【JVM】
    总结——》【Mysql】
    总结——》【Spring】
    总结——》【SpringBoot】

一、作用

在装载(Load)阶段,通过类的全限定名获取其定义的二进制字节流,需要借助类装载器完成,顾名思义,就是用来装载Class文件的。

二、分类

分类功能加载路径加载范围备注
Bootsrap加载核心jar$JAVA_HOME/jre/lib/rt.jar
-Xbootclassspath指定目录下的jar
sun.boot.class.pathC++实现
Extension加载扩展jar$JAVA_HOME/jre/lib/ext/*.jar
-Djava.ext.dirs指定目录下的jar
java.ext.dirs
App加载指定jarclasspath指定jar
-Djava.class.path指定目录下的jar和类
java.class.path
Custom加载自定义class实现ClassLoader

三、图解

类加载器
在这里插入图片描述

四、示例

1、类加载器

Q:当String.class文件被加载到内存后,都做了什么?
A:在内存里创建了2块内容
(1)方法区:存储类的信息
(2)堆:生成了class类的对象,并指向了方法区里的内容

public class T002_ClassLoaderLevel {
    public static void main(String[] args) {
        // null,原因:底层是C++实现的,java没有类和它对应,所以返回null
        System.out.println(String.class.getClassLoader());
        // null
        System.out.println(sun.awt.HKSCS.class.getClassLoader());

        // sun.misc.Launcher$ExtClassLoader@45ee12a7 ,位于ext包下的类
        System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());
        
        // sun.misc.Launcher$AppClassLoader@18b4aac2
        System.out.println(T002_ClassLoaderLevel.class.getClassLoader());

        // null
        System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader().getClass().getClassLoader());
        // null
        System.out.println(T002_ClassLoaderLevel.class.getClassLoader().getClass().getClassLoader());

        // sun.misc.Launcher$AppClassLoader@18b4aac2
        System.out.println(new T006_MSBClassLoader().getParent());
        
        // sun.misc.Launcher$AppClassLoader@18b4aac2,这是系统默认的classloader
        System.out.println(ClassLoader.getSystemClassLoader());
    }
}

2、父加载器

public class T004_ParentAndChild {
    public static void main(String[] args) {
        // sun.misc.Launcher$AppClassLoader@18b4aac2
        System.out.println(T004_ParentAndChild.class.getClassLoader());
        // null
        System.out.println(T004_ParentAndChild.class.getClassLoader().getClass().getClassLoader());
        // sun.misc.Launcher$ExtClassLoader@1540e19d
        System.out.println(T004_ParentAndChild.class.getClassLoader().getParent());
        // null
        System.out.println(T004_ParentAndChild.class.getClassLoader().getParent().getParent());
        // 报错 空指针
//        System.out.println(T004_ParentAndChild.class.getClassLoader().getParent().getParent().getParent());
    }
}

3、类加载器范围

public class T003_ClassLoaderScope {
    public static void main(String[] args) {
        String pathBoot = System.getProperty("sun.boot.class.path");
        System.out.println(pathBoot.replaceAll(";", System.lineSeparator()));

        System.out.println("--------------------");
        String pathExt = System.getProperty("java.ext.dirs");
        System.out.println(pathExt.replaceAll(";", System.lineSeparator()));

        System.out.println("--------------------");
        String pathApp = System.getProperty("java.class.path");
        System.out.println(pathApp.replaceAll(";", System.lineSeparator()));
    }
}

// 以下是运行结果

以下是sun.boot.class.path--------------------
D:\Java\jdk1.8.0_152\jre\lib\resources.jar
D:\Java\jdk1.8.0_152\jre\lib\rt.jar
D:\Java\jdk1.8.0_152\jre\lib\sunrsasign.jar
D:\Java\jdk1.8.0_152\jre\lib\jsse.jar
D:\Java\jdk1.8.0_152\jre\lib\jce.jar
D:\Java\jdk1.8.0_152\jre\lib\charsets.jar
D:\Java\jdk1.8.0_152\jre\lib\jfr.jar
D:\Java\jdk1.8.0_152\jre\classes

以下是java.ext.dirs--------------------
D:\Java\jdk1.8.0_152\jre\lib\ext
C:\Windows\Sun\Java\lib\ext

以下是java.class.path--------------------
D:\Java\jdk1.8.0_152\jre\lib\charsets.jar
D:\Java\jdk1.8.0_152\jre\lib\deploy.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar
D:\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar
D:\Java\jdk1.8.0_152\jre\lib\javaws.jar
D:\Java\jdk1.8.0_152\jre\lib\jce.jar
D:\Java\jdk1.8.0_152\jre\lib\jfr.jar
D:\Java\jdk1.8.0_152\jre\lib\jfxswt.jar
D:\Java\jdk1.8.0_152\jre\lib\jsse.jar
D:\Java\jdk1.8.0_152\jre\lib\management-agent.jar
D:\Java\jdk1.8.0_152\jre\lib\plugin.jar
D:\Java\jdk1.8.0_152\jre\lib\resources.jar
D:\Java\jdk1.8.0_152\jre\lib\rt.jar
E:\IdeaProjects_mine\msb\JVM\out\production\JVM
D:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\lib\idea_rt.jar

4、加载指定类loadClass(path)

public class T005_LoadClassByHand {
    public static void main(String[] args) throws ClassNotFoundException {
        Class clazz = T005_LoadClassByHand.class.getClassLoader().loadClass("com.mashibing.jvm.c2_classloader.T002_ClassLoaderLevel");
        System.out.println(clazz.getName());

        //利用类加载器加载资源,参考坦克图片的加载
        //T005_LoadClassByHand.class.getClassLoader().getResourceAsStream("");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值