2. 双亲委派机制
2.1 双亲委派机制工作原理
2.1.1 原理
- Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存,生成class对象。
- 加载某个类的class文件时,Java虚拟机采用的是双亲委派模式,即把请求交由父类处理,它是一种任务委派模式。
2.1.2 举例说明
- 自定义一个java.lang.String,然后在另外的类中调用String类,会发现只打印了"hello",没有打印"我是自定义加载类",也就是说,Java其实没有调用我们自定义的String类
| 这就是因为双亲委派机制,最上层的引导类加载器发现自己可以完成加载任务[BootStrap引导类加载器只加载包名为java、javax、sun等开头的类],所以就去加载了核心类库中的String类,没有加载用户自定义的String类。
| 而且核心类库中的String并没有main方法,在自定义的String类中运行main方法,加载的类是核心类库的String类,就会报找不到main方法的错误
- 假设项目中用到SPI接口,SPI属于核心API,需要使用引导类加载器,引导类加载器加载rt.jar,就加载了SPI核心类,之后用到了SPI接口,属于第三方jar包,不属于核心jar,需要用系统类加载器加载,所以就要反向委派,引导类加载器委派线程上下文加载器去加载SPI接口实现,就是说核心API用引导类加载器加载,第三方API用系统类加载器加载
2.2 双亲委派机制的优势
- 避免类的重复加载(一个类只会被一个类加载器加载,而且一定会被加载)。
- 保护程序安全,防止核心API被随意篡改
| 假设我们现在要在java.lang包下定义一个类MyString,类加载的时候,引导类加载器发现这个类归它加载,但是java.lang包需要访问权限,所以就会报错
2.3 沙箱安全机制
自定义String类,但是在加载自定义String类的时候会率先使用引导类加载器加载,而引导类加载器在加载过程中会先加载jdk自带的文件(rt.jar包中的javalangString.class),报错信息说没有main方法就是因为加载的是rt.jar包中的String类。这样可以保证对java核心源代码的保护,这就是沙箱安全机制。