类加载机制--双亲委派模式

Java虚拟机先从最核心的API开始查找,防止不可信的类扮演被信任的类。

双亲委派模型原理图:
在这里插入图片描述
关键类:

启动类加载器 Bootstrap ClassLoader:加载<JAVA_HOME>\lib目录下核心库
扩展类加载器 Extension ClassLoader:加载<JAVA_HOME>\lib\ext目录下扩展包
应用程序类加载器 Application ClassLoader: 加载用户路径(classpath)上指定的类库

“双亲委派”机制加载Class的具体过程:
实现双亲委派模型的代码都集中在java.lang.ClassLoader的loadClass()方法中,具体过程如下:

1,源ClassLoader先判断该Class是否已加载,如果已加载,则返回Class对象;如果没有则委托给父类加载器(Extension ClassLoader)。

2,父类加载器判断是否加载过该Class,如果已加载,则返回Class对象;如果没有则委托给祖父类加载器。
依此类推,直到始祖类加载器(Bootstrap ClassLoader)(引用类加载器)。

3,始祖类加载器(Bootstrap ClassLoader)判断是否加载过该Class,如果已加载,则返回Class对象;如果没有则尝试从其对应的类路径下寻找class字节码文件并载入。如果载入成功,则返回Class对象;如果载入失败,则委托给始祖类加载器的子类加载器。

4,始祖类加载器(Bootstrap ClassLoader)的子类加载器(Extension ClassLoader)尝试从其对应的类路径下寻找class字节码文件并载入。如果载入成功,则返回Class对象;如果载入失败,则委托给始祖类加载器的孙类加载器(Application ClassLoader)。依此类推,直到源ClassLoader。

5,源ClassLoader尝试从其对应的类路径下寻找class字节码文件并载入。如果载入成功,则返回Class对象;如果载入失败,源ClassLoader不会再委托其子类加载器,而是抛出ClassNotFoundException异常。

在右侧的三个小标签里,列举了此层类加载器主要加载的代表性类库,事实上不止如此。

通过如下代码可以查看 Bootstrap 所有已经加载的类库:
在这里插入图片描述
执行结果如下:
在这里插入图片描述

双亲委派模型要求除顶层启动类加载器外其余类加载器都应该有自己的父类加载器;类加载器之间通过复用关系来复用父加载器的代码。

双亲委派模型的实现过程:

实现双亲委派模型的代码都集中在java.lang.ClassLoader的loadClass()方法中:
首先会检查请求加载的类是否已经被加载过;
若没有被加载过:
递归调用父类加载器的loadClass();
父类加载器为空后就使用启动类加载器加载;
如果父类加载器和启动类加载器均无法加载请求,则调用自身的加载功能。

双亲委派模型的优点:
Java类伴随其类加载器具备了带有优先级的层次关系,确保了在各种加载环境的加载顺序。
保证了运行的安全性,防止不可信类扮演可信任的类。

参考博文:https://blog.csdn.net/zhangzeyuaaa/article/details/42499839

猜你喜欢

转载自blog.csdn.net/qq_38946877/article/details/87884447