JVM学习笔记(四)

双亲委派机制

  • 概念

    当一个类加载器接收到类加载请求后,自己先不去加载,而是查看是否有父类加载器,如果有,那么就

    提交给父类加载器,如果父类加载器还存在父类加载器,就继续提交,直到最后提交到引导类加载器,

    引导类加载器会查看是不是归自己管,比如说核心类就归引导类加载,如果归自己管,就检验一下请求

    方是否有权限,如果有权限就直接完成加载,否则就拒绝加载,并抛出非法进入异常。如果发现不归自

    己管,那么就反向委派,向下提交,比如提交至扩展类加载器,归自己管就执行加载,否则继续向下递

    交,最后直到系统类加载器加载。

    • 注意,类加载操作只会由一个类加载器执行一次,也就是一个类加载器完成了加载,就不会再递交

      给别的加载器加载了。

    • 图解

JVM学习笔记(四)

  • 特殊例子

    在某些情况下,我们可能在自定义类中实现了核心包中的接口,同样是采用双亲委派机制,但是比较

    特殊,核心包中的接口由引导类加载器加载,但具体的自定义实现类不归它加载,于是就委托给线程

    上下文类加载器加载,默认为系统类加载器加载。

  • 好处

    1. 避免了类的重复加载

    2. 很好的保护了核心类库api,防止被篡改,也就是沙箱安全机制

      比如:

      • 自定义类:java.lang.String

        与核心api重名,根据双亲委派机制,引导类会加载核心api中的String,忽略掉自定义String类,

        如果不采用该机制,那么自定义的String将有可能被加载,那将会导致非常崩溃的情况,比如功能

        无法实现,项目信息泄露等等。

      • 自定义类:java.lang.MyClass

        包名的命名与核心api包重合,那么理论上就会由引导类加载器完成加载,可是经过检验发现是没

        有权限访问核心包路径的,那么就会拒绝加载,避免对引导类加载器本身与核心包造成威胁。