雙親委派機制


雙親委派機制的作用

  • 確保Java核心類庫的安全:所有的Java應用都至少會引用java.lang.Object類,也就是說在運行期,java.lang.Object類會被記載到Java虛擬機當中;如果這個加載過程是由Java應用自己的類加載器所完成的,那么可能會在JVM中存在多個版本的java.lang.Object類,而且這些類還是不兼容的、相互不可見的(因為命名空間的原因)。借助父親委托機制,Java核心類庫中的類的加載工作都是由啟動類加載器來統一完成的,從而確保了Java應用所使用的都是同一個版本的Java核心類庫,他們之間是互相兼容的。
  • 確保Java核心類庫提供的類不會被自定義的類所替代。
  • 不同的類加載器可以為相同名稱(binary name)的類創建額外的命名空間。相同名稱的類可以並存在Java虛擬機中,只需要用不同的類加載器來加他們即可,不同類加載器所加載的類是不兼容的,這就相當於在Java虛擬機內部創建了一個又一個相互隔離的Java類空間。



什么是雙親委派機制

當某個類加載器需要加載某個.class文件時,它首先把這個任務委托給他的上級類加載器,遞歸這個操作,如果上級的類加載器沒有加載,自己才會去加載這個類。

類加載器的類別

BootstrapClassLoader(啟動類加載器)

c++編寫,加載java核心庫 java.*,構造ExtClassLoaderAppClassLoader。由於引導類加載器涉及到虛擬機本地實現細節,開發者無法直接獲取到啟動類加載器的引用,所以不允許直接通過引用進行操作

ExtClassLoader (標准擴展類加載器)

java編寫,加載擴展庫,如classpath中的jre ,javax.*或者
java.ext.dir 指定位置中的類,開發者可以直接使用標准擴展類加載器。

AppClassLoader(系統類加載器)

java編寫,加載程序所在的目錄,如user.dir所在的位置的class

CustomClassLoader(用戶自定義類加載器)

java編寫,用戶自定義的類加載器,可加載指定路徑的class文件

源碼分析

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // 首先檢查這個classsh是否已經加載過了 Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { // c==null表示沒有加載,如果有父類的加載器則讓父類加載器加載 if (parent != null) { c = parent.loadClass(name, false); } else { //如果父類的加載器為空 則說明遞歸到bootStrapClassloader了 //bootStrapClassloader比較特殊無法通過get獲取 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) {} if (c == null) { //如果bootstrapClassLoader 仍然沒有加載過,則遞歸回來,嘗試自己去加載class long t1 = System.nanoTime(); c = findClass(name); sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } } 

委派機制的流程圖

 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM