JVM类加载类的分类

15 篇文章 1 订阅

JVM类加载类的分类

虚拟机自带的加载器

  • 启动类加载器(引导类加载器,Bootstrap ClassLoader)

    1. 这个类加载使用C/C++语言实现的,嵌套在JVM内部。
    2. 它用来加载Java中的核心库((JAVA_HOME/jre/lib/rt.jar、resources.jar或sun.boot.class.pa路径下的内容),用于提供JVM自身需要的类)
    3. 并不继承自java.lang.classLoader,没有父加载器。
    4. 加载扩展类和应用程序类加载器,并指定为他们的父类加载器。
      出于安全考虑,Bootstrap启动类加载器只加载sun等开头的类
  • 扩展类加载器(Extension classLoader)

    1. Java语言编写,由sun.misc.Launcher$ExtClassLoader实现。
    2. 派生于classLoader类
    3. 父类加载器为启动类加载器
    4. 从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安
      装目录的jre/lib/ext子目录(扩展目录)下加载类库。如果用户创
      建的JAR放在此目录下,也会自动由扩展类加载器加载。
  • 应用程序类加载器(系统类加载器,AppclassLoader)

    1. java语言编写,由sun.misc.Launcher$AppClassLoader实现
    2. 派生于classLoader类
    3. 父类加载器为扩展类加载器
    4. 它负责加载环境变量classpath或系统属性java.class.path指定路径下的类库
    5. 该类加载是程序中默认的类加载器,一般来说,Java应用的类都是由
      它来完成加载
    6. 通过classLoader#getsystemClassLoader()方法可以获取到该
      类加载器
  • 用户自定义类加载器

    在Java的日常应用程序开发中,类的加载几乎是由上述3种类加载器相互
    配合执行的,在必要时,我们还可以自定义类加载器,来定制类的加载方
    式。

  • 为什么要自定义类加载器?

    隔离加载类
    修改类加载的方式
    扩展加载源
    防止源码泄漏

图解:

在这里插入图片描述

代码如下:

package com.lbl.ClassLoaderTest;

public class ClassLoaderTest {
    public static void main(String[] args) {
        //获取系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);//sun.misc.Launcher$AppCLassLoader@18b4aac2
        //获取其上层:扩展类加载器
        ClassLoader extClassLoader = systemClassLoader.getParent();
        System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLdader@1540e19d
        //获取其上层:获取不到引导类加载器
        ClassLoader bootstrapClassLoader = extClassLoader.getParent();
        System.out.println(bootstrapClassLoader);//null

        //对于用户自定义类来说:默认使用系统类加载器进行加载
        ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
        System.out.println(classLoader);// sun.misc.Launcher$AppClassLoader@18b4aac2
        
        ClassLoader classLoader1 = String.class.getClassLoader();
        //String类使用引导类加载器进行加载的。--->Java的核心类库都是使用引导类加载器进行加载的。
        System.out.println(classLoader1);//null
    }

}

运行结果:

在这里插入图片描述

再来测试一下引导类加载器:

代码:

package com.lbl.ClassLoaderTest;

import java.net.URL;

public class ClassLoaderTest02 {
    public static void main(String[] args) {
        System.out.println("***********启动类加载器***********");
        //获取BootstrapCLassLoader能够加载的api的路径
        URL[] urLs = sun.misc.Launcher.getBootstrapClassPath().getURLs();
        for (URL element : urLs) {
            System.out.println(element.toExternalForm());
        }
       
    }
}

运行效果:

在这里插入图片描述

找到file:/C:/Program%20Files/Java/jdk1.8.0_172/jre/lib/jsse.jar文件,然后解压,进入com.sun.net.ssl.internal.ssl文件夹,找到Provider.class如下图:

在这里插入图片描述

然后添加如下代码:

        //从上面的路径中随意选择一个类,来看看他的类加载器是什么:
        ClassLoader classLoader = Provider.class.getClassLoader();
        System.out.println(classLoader);

在这里插入图片描述

完整代码如下:

package com.lbl.ClassLoaderTest;

import java.net.URL;
import java.security.Provider;

public class ClassLoaderTest02 {
    public static void main(String[] args) {
        System.out.println("***********启动类加载器***********");
        //获取BootstrapCLassLoader能够加载的api的路径
        URL[] urLs = sun.misc.Launcher.getBootstrapClassPath().getURLs();
        for (URL element : urLs) {
            System.out.println(element.toExternalForm());
        }
        //从上面的路径中随意选择一个类,来看看他的类加载器是什么:
        ClassLoader classLoader = Provider.class.getClassLoader();
        System.out.println(classLoader);
    }
}

再来测试一下扩展类加载器:

代码如下:

package com.lbl.ClassLoaderTest;


public class ClassLoaderTest03 {
    public static void main(String[] args) {
        System.out.println("*********扩展类加载器*********");
        String extDirs = System.getProperty("java.ext.dirs" );
        for (String path : extDirs.split(";"))
        System.out.println(path);
    }
}

运行效果:

在这里插入图片描述

找到C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext文件夹,图片如下:

在这里插入图片描述

解压:sunec.jar,进入sunec\sun\security\ec找到CurveDB.class,如下图:

在这里插入图片描述

添加好下代码:

//在上面的路径中随意挑选一个类,来看看他有类加载器是什么
        ClassLoader classLoader = CurveDB.class.getClassLoader();
        System.out.println(classLoader); 	

完整代码如下:

package com.lbl.ClassLoaderTest;


import sun.security.ec.CurveDB;

public class ClassLoaderTest03 {
    public static void main(String[] args) {
        System.out.println("*********扩展类加载器*********");
        String extDirs = System.getProperty("java.ext.dirs" );
        for (String path : extDirs.split(";"))
        System.out.println(path);
    //在上面的路径中随意挑选一个类,来看看他有类加载器是什么
        ClassLoader classLoader = CurveDB.class.getClassLoader();
        System.out.println(classLoader); 	//sun.misc.Launcher$ExtClassLoader@4554617c
    }
}

输出效果:

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值