双亲委派机制
由于Java虚拟机中有多个类加载器,双亲委派机制的核心是解决一个类到底由谁加载的问题。
💡双亲委派机制有什么用?
1.保证类加载的安全性
通过双亲委派机制避免恶意代码替换JDK中的核心类库,比如java.lang.String,确保核心类库的完整性和安全性。
2.避免重复加载
双亲委派机制可以避免同一个类被多次加载。
双亲委派机制指的是:当一个类加载器接收到加载类的任务时,会自底向上查找是否加载过,再由顶向下进行加载。

☘每个类加载器都有一个父类加载器,在类加载的过程中,每个类加载器都会先检查是否已经加载了该类,如果已经加载则直接返回,否则会将加载请求委派给父类加载器。

☘如果所有的父类加载器都无法加载该类,则由当前类加载器自己尝试加载。所以看上去是自顶向下尝试加载。

第二次再去加载相同的类,仍然会向上进行委派,如果某个类加载器加载过就会直接返回。

向下委派加载起到了一个加载优先级的作用。
☘案例:
com.itheima.my.C这个类在当前程序的classpath中,看看是如何加载的。
首先自底向上一层一层的查找,发现都没有被加载过:

之后再自定向下开始加载,每一级类加载器检查该类是不是在它的加载路径中:

💡问题1:如果一个类重复出现在三个类加载器的加载位置,应该由谁来加载?
启动类加载器加载,根据双亲委派机制,它的优先级是最高的。
💡问题2:在自己的项目中去创建一个java.lang.String类,会被加载吗?
不能,会返回启动类加载器加载在rt.jar包中的String类
💡问题3:在Java中如何使用代码的方式去主动加载一个类呢?
方式1:使用Class.forName方法,使用当前类的类加载器去加载指定的类。
方式2:获取到类加载器,通过类加载器的loadClass方法指定某个类加载器加载。
//获取main方法所在类的类加载器,应用程序类加载器
ClassLoader classLoader = Demo1.class.getClassLoader();
//使用应用程序类加载器加载com.itheima.my.A
classLoader.loadClass("com.itheima.my.A");
☘细节:
每个Java实现的类加载器中保存了一个成员变量叫"父”(Parent)类加载器,可以理解为它的上级,并不是继承关系。

🐟注:启动类加载器是使用C++编写,没有父类加载器。
在Arthas中可以通过classloader -t 查看类加载器的父子关系。
☀面试题(高频)
类的双亲委派机制是什么?
1、当一个类加载器去加载某个类的时候,会自底向上向父类查找是否加载过,如果加载过就直接返回,如果一直到最顶层的类加载器都没有加载,再由顶向下进行加载。
2、应用程序类加载器的父类加载器是扩展类加载器,扩展类加载器的父类加载器是启动类加载器。
3、双亲委派机制的好处有两点:第一是避免恶意代码替换JDK中的核心类库,比如java.lang.String,确保核心类库的完整性和安全性。第二是避免一个类重复地被加载。

945

被折叠的 条评论
为什么被折叠?



