Java中类加载器的具体种类
你想系统了解Java中类加载器的具体种类,包括每种加载器的核心作用、加载范围和关键特点——这是理解Java类加载机制的核心,我会结合“作用+加载范围+代码验证”的方式,让你清晰掌握不同类加载器的区别。
Java的类加载器体系基于双亲委派模型(请求加载类时,先委托父加载器加载,父加载器加载不到才自己加载),主要分为内置类加载器(3种核心)和自定义类加载器,下面逐一详解:
一、内置类加载器(JVM自带,核心种类)
这是JVM默认提供的类加载器,按“优先级从高到低”分为3类:
1. 启动类加载器(Bootstrap ClassLoader)
- 核心作用:加载JVM运行的核心类库,是整个类加载器体系的根。
- 实现特点:
- 不是Java实现(由C/C++编写),属于JVM内核的一部分;
- 没有对应的Java类(
ClassLoader的子类),通过getClassLoader()获取时返回null; - 最高优先级,没有父加载器。
- 加载范围:
- JDK安装目录下
jre/lib中的核心jar包(如rt.jar、charsets.jar,包含java.lang、java.util等核心包); - 也可通过
-Xbootclasspath参数手动指定加载路径。
- JDK安装目录下
2. 扩展类加载器(Extension ClassLoader)
- 核心作用:加载JDK的扩展功能类库,补充核心类库之外的扩展功能。
- 实现特点:
- 由Java实现(类名:
sun.misc.Launcher$ExtClassLoader); - 父加载器是启动类加载器(逻辑上的父,因为启动类加载器不是Java类)。
- 由Java实现(类名:
- 加载范围:
- JDK安装目录下
jre/lib/ext中的扩展jar包; - 也可通过
java.ext.dirs系统属性手动指定扩展类路径。
- JDK安装目录下
3. 应用程序类加载器(Application ClassLoader)
- 别名:系统类加载器(System ClassLoader),是日常开发中最常用的加载器。
- 核心作用:加载当前应用程序的类(我们自己写的代码、第三方依赖jar包)。
- 实现特点:
- 由Java实现(类名:
sun.misc.Launcher$AppClassLoader); - 父加载器是扩展类加载器;
- 是
ClassLoader.getSystemClassLoader()的返回值,也是默认的类加载器(未指定时,所有用户类都由它加载)。
- 由Java实现(类名:
- 加载范围:
- 应用的
classpath路径下的所有类(包括src/main/java编译后的class文件、Maven引入的第三方jar包); - 可通过
-cp或-classpath参数修改classpath。
- 应用的
代码验证:查看不同类的加载器
public class ClassLoaderDemo {
public static void main(String[] args) {
// 1. 核心类(如String):由启动类加载器加载(返回null)
ClassLoader stringClassLoader = String.class.getClassLoader();
System.out.println("String类的加载器:" + stringClassLoader); // null
// 2. 扩展类(如com.sun.nio.zipfs.ZipFileSystem):由扩展类加载器加载
ClassLoader extClassLoader = com.sun.nio.zipfs.ZipFileSystem.class.getClassLoader();
System.out.println("扩展类的加载器:" + extClassLoader); // sun.misc.Launcher$ExtClassLoader@xxx
// 3. 自定义类(当前类):由应用程序类加载器加载
ClassLoader appClassLoader = ClassLoaderDemo.class.getClassLoader();
System.out.println("自定义类的加载器:" + appClassLoader); // sun.misc.Launcher$AppClassLoader@xxx
// 4. 获取系统类加载器(即应用程序类加载器)
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println("系统类加载器:" + systemClassLoader); // sun.misc.Launcher$AppClassLoader@xxx
}
}
二、自定义类加载器(Custom ClassLoader)
- 核心作用:满足特殊的类加载需求(内置加载器无法覆盖的场景)。
- 实现方式:
- 继承
java.lang.ClassLoader类; - 重写
findClass()方法(推荐,不破坏双亲委派模型); - 若需自定义加载逻辑,也可重写
loadClass()(不推荐,会破坏双亲委派)。
- 继承
- 应用场景:
- 加载非
classpath路径下的类(如从网络、数据库、加密文件中加载类); - 实现类的热部署(如Tomcat的WebappClassLoader,为每个Web应用单独加载类);
- 对类进行加密/解密(加载前解密,防止类文件被反编译)。
- 加载非
简单自定义类加载器示例(加载指定路径的类)
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
// 自定义类加载器
public class CustomClassLoader extends ClassLoader {
// 自定义类加载路径
private String classPath;
public CustomClassLoader(String classPath) {
this.classPath = classPath;
}
// 重写findClass,加载指定路径的类
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
// 将类名转为路径(如com.example.Test → com/example/Test.class)
byte[] data = loadClassData(name);
// 调用父类方法,将字节数组转为Class对象
return defineClass(name, data, 0, data.length);
} catch (Exception e) {
throw new ClassNotFoundException(name);
}
}
// 读取类文件的字节数组
private byte[] loadClassData(String name) throws Exception {
name = name.replace(".", "/");
String path = classPath + "/" + name + ".class";
try (InputStream is = new FileInputStream(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
int b;
while ((b = is.read()) != -1) {
baos.write(b);
}
return baos.toByteArray();
}
}
// 测试自定义类加载器
public static void main(String[] args) throws Exception {
// 自定义类加载路径(替换为你的class文件所在路径)
CustomClassLoader loader = new CustomClassLoader("D:/custom_class");
// 加载自定义类
Class<?> clazz = loader.loadClass("com.example.Test");
System.out.println("自定义类的加载器:" + clazz.getClassLoader()); // CustomClassLoader@xxx
}
}
三、类加载器的核心规则:双亲委派模型
所有内置类加载器(除启动类)都遵循该模型,核心逻辑:
- 当类加载器收到加载请求时,先委托父加载器加载,自己不先处理;
- 父加载器若能加载,则返回Class对象;若加载不到(找不到类文件),子加载器才自己加载;
- 目的:保证核心类的唯一性和安全性(比如
java.lang.String只能由启动类加载器加载,避免自定义String类篡改核心逻辑)。
总结
- 内置类加载器分3类:启动类加载器(C++实现,加载核心库)、扩展类加载器(加载扩展库)、应用程序类加载器(加载应用类,默认加载器);
- 自定义类加载器需继承
ClassLoader,重写findClass(),用于特殊加载场景(如热部署、加密类加载); - 类加载器遵循双亲委派模型,优先委托父加载器加载,保证核心类的安全和唯一性。

浙公网安备 33010602011771号