专栏导航
目录
?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对象。
案例:
获取扩展类加载器:
public class ExtClassLoaderDemo {
public static void main(String[] args){
ClassLoader classLoader = ScriptEnvironment.class.getClassLoader();
System.out.println(classLoader);
}
}
运行结果:
通过将所需的jar包放入/jre/lib/ext目录下和使用参数进行扩展两种方法,开发者可以利用扩展类加载器来加载用户提供的JAR包。在使用时,请根据具体情况选择最适合的方式,并注意避免可能出现的冲突和问题。
一种直接的方法是将所需的jar包放入/jre/lib/ext目录下,让扩展类加载器能够加载到这个jar包中的类。尽管这种方法能够使 JAR 包被类加载器加载,但并不推荐。主要原因是这涉及到更改 JDK 安装目录中的内容,可能会引发不可预测的问题,也可能影响到 JDK 的升级。
推荐,使用-Djava.ext.dirs=jar包目录进行扩展。这种方式可以加载用户提供的 JAR 包,但是会覆盖原始目录。所以在Windows上,可以使用分号(;)来分隔多个目录,在MacOS和Linux上,可以使用冒号(:)来分隔多个目录。
案例:
加载jar包(省略用户JAR包打包步骤):
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包目录进行扩展:
-Djava.ext.dirs=jar包目录
-Djava.ext.dirs="D:\Java\jdk1.8.0_201\jre\lib\ext;D:\Test"
运行结果:
应用程序类加载器(Application Class Loader)也是JDK中提供的、使用Java编写的类加载器。它的主要任务是加载应用程序的classpath下的类文件。
案例:
获取应用程序类加载器:
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包、应用程序类加载器等内容,希望对大家有所帮助。