JVM工作原理与实战(十):类加载器-Java类加载器

前言

​JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了扩展类加载器、通过扩展类加载器去加载用户jar包、应用程序类加载器等内容。


在Java虚拟机(JVM)中,类加载器负责将类的字节码文件加载到内存中,并生成对应的Class对象。类加载器是Java虚拟机中的重要组成部分,其中Java代码实现的类加载器包括扩展类加载器和应用程序类加载器(JDK8及之前的版本)。

一、介绍

扩展类加载器和应用程序类加载器是JDK中提供的、使用Java编写的类加载器。它们是sun.misc.Launcher的静态内部类,并继承自URLClassLoader。这两个类加载器具备通过目录或指定jar包将字节码文件加载到内存中的能力。此外,它们还提供了更多的功能和灵活性,以支持Java应用程序的动态类加载需求。

ClassLoader 抽象类,定义了类加载器的具体行为模式,通过JNI调用底层的Java虚拟机方 法。
SecureClassLoader 使用证书机制提升类加载的安全性。
URLClassLoader 利用URL获取目录下或者指定的jar包进行加载,获取其字节码数据。
扩展类加载器****Extension 加载Java安装目录/jre/lib/ext下的类文件。
应用程序类加载器****Application 加载classpath下的类文件。

二、扩展类加载器

扩展类加载器(Extension Class Loader)是JDK中提供的一个功能强大的类加载器,它使用Java语言编写,用于加载Java安装目录/jre/lib/ext下的类文件。该加载器继承自Java的URLClassLoader类,具有高度的灵活性和可扩展性,能够根据需要动态地加载和卸载类文件,从而满足Java应用程序的多样化需求。

ClassLoader提供了许多方法来动态加载类,如loadClass()、defineClass()等。这些方法允许程序员在运行时动态地加载类的字节码文件,并生成对应的Class对象。

案例:

获取扩展类加载器:

arduino 复制代码
public class ExtClassLoaderDemo {
    public static void main(String[] args){
        ClassLoader classLoader = ScriptEnvironment.class.getClassLoader();
        System.out.println(classLoader);
    }
}

运行结果:

三、通过扩展类加载器去加载用户jar包

通过将所需的jar包放入/jre/lib/ext目录下和使用参数进行扩展两种方法,开发者可以利用扩展类加载器来加载用户提供的JAR包。在使用时,请根据具体情况选择最适合的方式,并注意避免可能出现的冲突和问题。

1.放入/jre/lib/ext下进行扩展

一种直接的方法是将所需的jar包放入/jre/lib/ext目录下,让扩展类加载器能够加载到这个jar包中的类。尽管这种方法能够使 JAR 包被类加载器加载,但并不推荐。主要原因是这涉及到更改 JDK 安装目录中的内容,可能会引发不可预测的问题,也可能影响到 JDK 的升级。

2.使用参数进行扩展

推荐,使用-Djava.ext.dirs=jar包目录进行扩展。这种方式可以加载用户提供的 JAR 包,但是会覆盖原始目录。所以在Windows上,可以使用分号(;)来分隔多个目录,在MacOS和Linux上,可以使用冒号(:)来分隔多个目录。

案例:

加载jar包(省略用户JAR包打包步骤):

ini 复制代码
public class Demo2 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.rye.test.Test");
        System.out.println(aClass);
        ClassLoader classLoader = aClass.getClassLoader();
        System.out.println(classLoader);
//        验证没有覆盖原始目录
        ClassLoader loader = ScriptEnvironment.class.getClassLoader();
        System.out.println(loader);
    }
}

使用-Djava.ext.dirs=jar包目录进行扩展:

ini 复制代码
-Djava.ext.dirs=jar包目录
ini 复制代码
-Djava.ext.dirs="D:\Java\jdk1.8.0_201\jre\lib\ext;D:\Test"

运行结果:

四、应用程序类加载器

应用程序类加载器(Application Class Loader)也是JDK中提供的、使用Java编写的类加载器。它的主要任务是加载应用程序的classpath下的类文件。

案例:

获取应用程序类加载器:

csharp 复制代码
public class AppClassLoader {
    public static void main(String[] args) {
        // 该项目创建的Student类
        Student student = new Student();
        ClassLoader classLoader = Student.class.getClassLoader();
        System.out.println(classLoader);

        // maven依赖中的类
        ClassLoader classLoader1 = FileUtils.class.getClassLoader();
        System.out.println(classLoader1);
    }
}

运行结果:


总结

JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了扩展类加载器、通过扩展类加载器去加载用户jar包、应用程序类加载器等内容,希望对大家有所帮助。

相关推荐
小松学前端1 分钟前
第六章 7.0 LinkList
java·开发语言·网络
Wx-bishekaifayuan8 分钟前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
customer0813 分钟前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
全栈开发圈15 分钟前
新书速览|Java网络爬虫精解与实践
java·开发语言·爬虫
WaaTong17 分钟前
《重学Java设计模式》之 单例模式
java·单例模式·设计模式
面试鸭19 分钟前
离谱!买个人信息买到网安公司头上???
java·开发语言·职场和发展
无尽的大道1 小时前
Java反射原理及其性能优化
jvm·性能优化