1. 程式人生 > >Java你需要知道的知識-簡明闡述雙親委派機制及作用

Java你需要知道的知識-簡明闡述雙親委派機制及作用

# 1、雙親委派機制及作用 ## 1.1 什麼是雙親委派機制 當某個類載入器需要載入某個`.class`檔案時,它首先把這個任務委託給他的上級類載入器,遞迴這個操作,如果上級的類載入器沒有載入,自己才會去載入這個類。 ## 1.2 類載入器的類別 #### BootstrapClassLoader(啟動類載入器) `c++`編寫,載入`java`核心庫 `java.*`,構造`ExtClassLoader`和`AppClassLoader`。由於引導類載入器涉及到虛擬機器本地實現細節,開發者無法直接獲取到啟動類載入器的引用,所以不允許直接通過引用進行操作 #### ExtClassLoader (標準擴充套件類載入器) `java`編寫,載入擴充套件庫,如`classpath`中的`jre` ,`javax.*`或者 `java.ext.dir` 指定位置中的類,開發者可以直接使用標準擴充套件類載入器。 #### AppClassLoader(系統類載入器) ``` java`編寫,載入程式所在的目錄,如`user.dir`所在的位置的`class ``` #### CustomClassLoader(使用者自定義類載入器) `java`編寫,使用者自定義的類載入器,可載入指定路徑的`class`檔案 ## 1.3 原始碼分析 ```java 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; } } ``` ## 1.4 委派機制的流程圖 ![](https://img2020.cnblogs.com/blog/349139/202103/349139-20210318091212790-1424610271.png) ## 1.5 雙親委派機制的作用 1、防止重複載入同一個`.class`。通過委託去向上面問一問,載入過了,就不用再載入一遍。保證資料安全。 2、保證核心`.class`不能被篡改。通過委託方式,不會去篡改核心`.clas`,即使篡改也不會去載入,即使載入也不會是同一個`.class`物件了。不同的載入器載入同一個`.class`也不是同一個`Class`物件。這樣保證了`Class`執行