Java类加载器
Java类加载器(Class Loader)是Java虚拟机(JVM)的一部分,负责将编译后的Java字节码加载到JVM中并解析为可执行的Java类。类加载器是Java中重要的概念之一,它提供了动态加载类的能力,使得Java应用程序可以在运行时加载和使用编译时不存在的类。
类加载器的作用
类加载器的主要作用是将类的字节码加载到JVM中并转化为Java类。在Java应用程序运行过程中,当需要使用某个类时,JVM会先检查该类是否已经加载,如果没有加载则会使用类加载器将其加载到JVM中。
类加载器的主要任务包括:
- 加载:通过类的全限定名(Fully Qualified Name)查找并加载对应的字节码文件。
- 验证:校验加载的字节码文件是否符合Java语言的规范,例如文件格式是否正确、安全性检查等。
- 准备:为类的静态变量分配内存空间,并设置默认值。
- 解析:将类或接口的二进制名称解析为对应的引用,例如将类的全限定名解析为JVM内部的表示形式。
- 初始化:执行类的初始化代码,包括静态变量赋值、静态代码块等。
- 使用:类加载完成后,可以通过其创建对象、调用方法等操作。
类加载器的层次结构
Java类加载器的层次结构如下所示:
classDiagram
class ClassLoader
ClassLoader <|-- BootstrapClassLoader
ClassLoader <|-- ExtensionClassLoader
ClassLoader <|-- ApplicationClassLoader
ClassLoader <|-- CustomClassLoader
- BootstrapClassLoader(启动类加载器):负责加载JVM本身所需要的类库,例如
rt.jar等。 - ExtensionClassLoader(扩展类加载器):负责加载JVM的扩展类库,例如
ext目录下的JAR文件。 - ApplicationClassLoader(应用程序类加载器):负责加载应用程序的类,例如
classpath下的类。 - CustomClassLoader(自定义类加载器):开发者可以通过继承ClassLoader类实现自己的类加载器。
类加载器之间通过双亲委派(Parent Delegation)模型进行加载,即当一个类加载器需要加载某个类时,它会先将该请求委派给父加载器进行加载,只有父加载器无法加载时才由子加载器尝试加载。这种机制可以保证Java核心类库的安全性,并避免类的重复加载。
下面是一个示例代码,演示了类加载器的层次结构:
public class ClassLoaderDemo {
public static void main(String[] args) {
ClassLoader classLoader = ClassLoaderDemo.class.getClassLoader();
System.out.println("ClassLoader: " + classLoader);
System.out.println("Parent ClassLoader: " + classLoader.getParent());
System.out.println("Grandparent ClassLoader: " + classLoader.getParent().getParent());
}
}
输出结果为:
ClassLoader: jdk.internal.loader.ClassLoaders$AppClassLoader@70dea4e
Parent ClassLoader: jdk.internal.loader.ClassLoaders$PlatformClassLoader@5c647e05
Grandparent ClassLoader: null
从输出结果可以看出,ClassLoaderDemo类使用的是应用程序类加载器(ApplicationClassLoader),其父加载器是扩展类加载器(ExtensionClassLoader),扩展类加载器的父加载器是启动类加载器(BootstrapClassLoader)。
类加载器的使用
类加载器的使用非常简单,只需要使用ClassLoader类的loadClass方法即可加载指定类。下面是一个示例代码,演示了如何使用类加载器加载类:
public class ClassLoaderExample {
public static void main(String[] args) throws ClassNotFoundException {
// 使用BootstrapClassLoader加载类
ClassLoader bootstrapClassLoader = null;
Class<?> bootstrapClass = bootstrapClassLoader.loadClass("java.lang.String");
System.out.println("BootstrapClassLoader: " + bootstrapClass.getClassLoader());
// 使用ExtensionClassLoader加载类
ClassLoader extensionClassLoader = ClassLoaderExample.class.getClassLoader().getParent();
Class<?> extensionClass = extensionClassLoader.loadClass("com.example.MyClass");
System.out.println("ExtensionClassLoader: " + extensionClass.getClassLoader
















