类加载的双亲委派机制
類加載器的雙親委派機制
? 除了根類加載器之外,其他的類加載器都需要有自己的父加載器。從JDK1.2開始,類的加載過程采用雙親委派機制,這種機制能夠很好的保護java程序的安全。除了虛擬機自帶的根類加載器之外,其余的類加載器都有唯一的父加載器。比如,如果需要classLoader加載一個類時,該classLoader先委托自己的父加載器先去加載這個類,若父加載器能夠加載,則由父加載器加載,否則才有classLoader自己加載這個類。即每個類加載器都很懶,加載類時都先讓父加載器去嘗試加載,一直到根類加載器,加載不到時自己才去加載。真正加載類的加載器我們叫做啟動類加載器。注意,雙親委派機制的父子關系并非面向對象程序設計中的繼承關系,而是通過使用組合模式來復用父加載器代碼,這種機制如下圖所示:
public class ClassLoaderDemo1 {public static void main(String[] args) throws Exception{//演示類加載器的父子關系ClassLoader loader = ClassLoaderDemo1.class.getClassLoader();while(loader!=null){System.out.println(loader);loader = loader.getParent();}} } 運行結果: sun.misc.Launcher$AppClassLoader@18b4aac2 sun.misc.Launcher$ExtClassLoader@1b6d3586使用雙親委派機制的好處:
1、可以避免類的重復加載,當父類加載器已經加載了該類時,就沒有必要子ClassLoader再加載一次。
2、考慮到安全因素,java核心api中定義類型不會被隨意替換,假設通過網絡傳遞一個名為java.lang.Object的類,通過雙親委托模式傳遞到啟動類加載器,而啟動類加載器在核心Java API發現這個名字的類,發現該類已被加載,并不會重新加載網絡傳遞的過來的java.lang.Object,而直接返回已加載過的Object.class,這樣便可以防止核心API庫被隨意篡改。
//定義一個類,注意包名 package java.lang;public class MyObject {} //加載該類 public static void main(String[] args) {Class clazz = MyObject.class;System.out.println(clazz.getClassLoader()); } //輸出結果 Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.lang因為java.lang包屬于核心包,只能由根類加載器進行加載,而根據類加載的雙親委派機制,根類加載器是加載不到這個MyObject類的(自定義的),所以只能由AppClassLoader進行加載,而這又不是允許的,所以會報出“Prohibited package name: java.lang”(禁止的包名)錯誤。
?
總結
以上是生活随笔為你收集整理的类加载的双亲委派机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内置类加载器小结
- 下一篇: ClassLoader简介