当前位置: 首页 > >

Java双亲委派机制

发布时间:

预定义类加*骱退孜苫





JVM预定义的三种类型类加*鳎





启动(Bootstrap)类加*鳎菏怯帽镜卮胧迪值睦嘧叭肫鳎涸鸾 /lib下面的类库加载到内存中(比如rt.jar)。由于引导类加*魃婕暗叫槟饣镜厥迪窒附冢⒄呶薹ㄖ苯踊袢〉狡舳嗉釉*鞯囊茫圆辉市碇苯油ü媒胁僮鳌

标准扩展(Extension)类加*鳎菏怯 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的。它负责将< Java_Runtime_Home >/lib/ext或者由系统变量 java.ext.dir指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加*鳌

系统(System)类加*鳎菏怯 Sun 的 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。它负责将系统类路径(CLASSPATH)中指定的类库加载到内存中。开发者可以直接使用系统类加*鳌

除了以上列举的三种类加*鳎褂幸恢直冉咸厥獾睦嘈 ? 线程上下文类加*鳌





双亲委派机制描述?

某个特定的类加*髟诮拥郊釉乩嗟那肭笫保紫冉釉厝挝裎懈咐嗉釉*鳎来蔚莨椋绻咐嗉釉*骺梢酝瓿衫嗉釉厝挝瘢统晒Ψ祷兀恢挥懈咐嗉釉*魑薹ㄍ瓿纱思釉厝挝袷保抛约喝ゼ釉亍





?


启动类加*





Java虚拟机的第一个类加*魇荁ootstrap,这个加*骱芴厥猓皇荍ava类,因此它不需要被别人加载,它嵌套在Java虚拟机内核里面,也就是JVM启动的时候Bootstrap就已经启动,它是用C++写的二进制代码(不是字节码),它可以去加载别的类。





这也是我们在测试时为什么发现System.class.getClassLoader()结果为null的原因,这并不表示System这个类没有类加*鳎撬募釉*鞅冉咸厥猓荁ootstrapClassLoader,由于它不是Java类,因此获得它的引用肯定返回null。





委托机制具体含义?

当Java虚拟机要加载一个类时,到底派出哪个类加*魅ゼ釉啬兀





首先当前线程的类加*魅ゼ釉叵叱讨械牡谝桓隼啵偕栉郃)。?

注:当前线程的类加*骺梢酝ü齌hread类的getContextClassLoader()获得,也可以通过setContextClassLoader()自己设置类加*鳌

如果类A中引用了类B,Java虚拟机将使用加载类A的类加*魅ゼ釉乩郆。


还可以直接调用ClassLoader.loadClass()方法来指定某个类加*魅ゼ釉啬掣隼唷



委托机制的意义 ? 防止内存中出现多份同样的字节码?

比如两个类A和类B都要加载System类:





如果不用委托而是自己加载自己的,那么类A就会加载一份System字节码,然后类B又会加载一份System字节码,这样内存中就出现了两份System字节码。

如果使用委托机制,会递归的向父类查找,也就是首选用Bootstrap尝试加载,如果找不到再向下。这里的System就能在Bootstrap中找到然后加载,如果此时类B也要加载System,也从Bootstrap开始,此时Bootstrap发现已经加载过了System那么直接返回内存中的System即可而不需要重新加载,这样内存中就只有一份System的字节码了。

?

面试题





能不能自己写个类叫java.lang.System?





答案:通常不可以,但可以采取另类方法达到这个需求。?

解释:为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸们优先,爸爸们能找到的类,儿子就没有机会加载。而System类是Bootstrap加*骷釉氐模退阕约褐匦矗沧苁鞘褂肑ava系统提供的System,自己写的System类根本没有机会得到加载。





但是,我们可以自己定义一个类加*骼创锏秸飧瞿康模吮苊馑孜谢疲飧隼嗉釉*饕脖匦胧翘厥獾摹S捎谙低匙源娜隼嗉釉*鞫技釉靥囟柯枷碌睦啵绻颐亲约旱睦嗉釉*鞣旁谝桓鎏厥獾哪柯迹敲聪低车募釉*骶臀薹釉兀簿褪亲钪栈故怯晌颐亲约旱募釉*骷釉亍



友情链接: