一天正在宿舍里忙着写代码。突然,老师给我布置了一项新任务:优化他正在开发的项目中的类加载机制。我对类加载器了解不多,开始翻阅各种资料,逐渐了解了Java中的类加载器机制。尤其是当读到双亲委派模型时,脑海中豁然开朗。仿佛看到了类加载请求在层层递进、逐步传递的画面,像极了树状结构中的节点。于是,决定写一篇博客,把自己的理解分享给更多的开发者。
什么是双亲委派模型
在Java中,类加载器(ClassLoader)是一个非常重要的组件,用于在运行时动态加载类文件。而双亲委派模型则是类加载器的一种重要机制,它规定了类加载请求的传递顺序,从而确保了Java类加载过程的安全性和稳定性。
双亲委派模型的原理
当一个类加载器收到类加载请求时,它不会自己直接去加载这个类,而是首先将请求委派给它的父类加载器。如果父类加载器无法完成这个加载请求,子类加载器才会尝试自己去加载。
类加载器的层次结构
有一张图比较形象:
在Java中,类加载器大致分为三种:
-
启动类加载器(Bootstrap ClassLoader):
- 负责加载Java核心类库,如
rt.jar
。 - 由JVM内部实现,没有父加载器。
- 负责加载Java核心类库,如
-
扩展类加载器(Extension ClassLoader):
- 负责加载扩展类库,如
lib/ext
目录下的类。 - 启动类加载器的子类加载器。
- 负责加载扩展类库,如
-
应用程序类加载器(Application ClassLoader):
- 负责加载用户类路径(classpath)上指定的类。
- 扩展类加载器的子类加载器。
双亲委派的优点
这种层层委派的机制保证了Java核心类库的安全性。例如,java.lang.Object
类总是由顶层的启动类加载器(Bootstrap ClassLoader)加载,从而避免了用户自定义的类库篡改核心类库的风险。
小实践
在编译层面:
java.lang
包的类被编译成字节码文件,并被打包在rt.jar
(运行时库)中。rt.jar
文件位于 JDK 的lib
目录下。- 绝对路径:C:\Program Files\Java\jdk1.8.0_261\jre\lib\rt.jar!\java\lang\ClassLoader.class