其实这个翻译就很容易引起歧义,英文原名叫Parents Delegation Model
,个人感觉叫官僚模型或啃老模型更合适一些,因为整个流程里面并没有体现到“双亲”在哪里。
概述
JVM采用按需加载类的模式,当需要加载某一类时,会将请求交由父类加载器处理,直至最顶层引导类加载器结束。
- 类加载器收到加载请求,将请求转发给父级类加载器
- 如果父类加载器还存在父加载器,那么继续向上转发,直至最顶层
- 若引导类加载器可以完成类加载,那么成功并返回;如果无法完成则反向交由下级加载器进行加载,直至加载成功
例子
根据上一篇文章中对类加载器的解释,首先系统类加载器接收到加载java.lang.String
的请求,然后由双亲委派模型交由扩展类加载器,再传递至引导类加载器结束。由于java.lang.String
属于系统核心类库,在引导类加载器的职能范围之内,对其加载并返回。所以此时创建的对象仍然是Java自己的String类。
在当前的String类中执行main方法会报错,原理和上一个例子中一样,因为他加载的是系统核心API,其String类中并没有main方法,因此报错
好处
显而易见,最重要的是可以保护java核心API不受篡改,其次可以避免重复加载,保证性能。
想象一个场景,某银行系统要与一个外部平台做API对接,对方发过来一个SDK,然后在里面一个不起眼的地方放了一个java.util.HashMap
,然后故意留了几个bug或者后门在里面。结果银行开发人员引进来SDK一不注意引用了第三方的HashMap,后果可想而知。(java.util
包位于rt.jar
,仍然是引导类加载器负责加载)
JVM严格到即便类名不同,也不允许使用系统核心包路径,看以下例子,会抛出一个安全错误