题目
请解释Java类加载机制中的双亲委派模型及其工作过程
信息
- 类型:问答
- 难度:⭐
考点
类加载器层次结构,双亲委派模型,类加载过程
快速回答
双亲委派模型是Java类加载的核心机制,工作过程分为三步:
- 当类加载器收到加载请求时,先委托父加载器尝试加载
- 若父加载器无法完成加载(搜索范围内未找到),子加载器才尝试加载
- 所有父加载器均失败后,最终由发起请求的加载器完成加载
该模型通过层级委托确保核心类库安全,避免重复加载。
解析
一、原理说明
双亲委派模型(Parent Delegation Model)是Java类加载的核心安全机制:
- 层级结构:类加载器分为四层(自上而下):
- Bootstrap ClassLoader(启动类加载器)
- Extension ClassLoader(扩展类加载器)
- Application ClassLoader(应用类加载器)
- 自定义ClassLoader
- 核心目标:
- 避免重复加载:确保类在JVM中唯一
- 保护核心类库:防止用户覆盖java.lang.Object等核心类
二、工作流程详解
以加载com.example.MyClass为例:
- 应用类加载器收到请求,先委托给父加载器(扩展类加载器)
- 扩展类加载器继续委托给父加载器(启动类加载器)
- 启动类加载器在
JRE/lib目录查找,若未找到则返回失败 - 扩展类加载器在
JRE/lib/ext目录查找,若未找到则返回失败 - 应用类加载器在
CLASSPATH中查找并加载类

(示意图:请求自下而上委托,加载自上而下尝试)
三、代码示例
// 验证类加载器层级
public class ClassLoaderDemo {
public static void main(String[] args) {
// 获取当前类的加载器(通常是ApplicationClassLoader)
ClassLoader loader = ClassLoaderDemo.class.getClassLoader();
System.out.println("当前加载器:" + loader);
// 逐级向上查询父加载器
System.out.println("父加载器:" + loader.getParent()); // ExtensionClassLoader
System.out.println("祖父加载器:" + loader.getParent().getParent()); // Bootstrap(显示为null)
}
}
/* 输出示例:
当前加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
父加载器:sun.misc.Launcher$ExtClassLoader@610455d6
祖父加载器:null // Bootstrap加载器由C++实现,Java中不可见
*/四、最佳实践
- 自定义类加载器时务必重写
findClass()而非loadClass(),以保持委派逻辑 - 需要打破双亲委派的场景(如OSGi):谨慎设计,确保理解安全风险
- 通过
-verbose:classJVM参数调试类加载过程
五、常见错误
- 覆盖核心类:尝试自定义
java.lang.String会导致SecurityException - 类冲突:相同类被不同加载器加载,导致
ClassCastException - 内存泄漏:未正确卸载动态加载的类(常见于热部署场景)
六、扩展知识
- 打破双亲委派的场景:
- JDBC通过
ServiceLoader加载驱动(SPI机制) - Tomcat为每个Web应用单独隔离类加载
- JDBC通过
- 类卸载条件:满足以下三点时,类可被GC回收
- 无该类的实例
- 加载该类的ClassLoader被回收
- 无
Class对象引用