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

風雨無阻415發表於2021-03-18

1、雙親委派機制及作用

1.1 什麼是雙親委派機制

當某個類載入器需要載入某個.class檔案時,它首先把這個任務委託給他的上級類載入器,遞迴這個操作,如果上級的類載入器沒有載入,自己才會去載入這個類。

1.2 類載入器的類別

BootstrapClassLoader(啟動類載入器)

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

ExtClassLoader (標準擴充套件類載入器)

java編寫,載入擴充套件庫,如classpath中的jrejavax.*或者
java.ext.dir 指定位置中的類,開發者可以直接使用標準擴充套件類載入器。

AppClassLoader(系統類載入器)

java`編寫,載入程式所在的目錄,如`user.dir`所在的位置的`class

CustomClassLoader(使用者自定義類載入器)

java編寫,使用者自定義的類載入器,可載入指定路徑的class檔案

1.3 原始碼分析

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 委派機制的流程圖

1.5 雙親委派機制的作用

1、防止重複載入同一個.class。通過委託去向上面問一問,載入過了,就不用再載入一遍。保證資料安全。
2、保證核心.class不能被篡改。通過委託方式,不會去篡改核心.clas,即使篡改也不會去載入,即使載入也不會是同一個.class物件了。不同的載入器載入同一個.class也不是同一個Class物件。這樣保證了Class執行安全。

相關文章