[JAVA面試]-談談你對雙親委派機制的了解
在介紹雙親委派機制前,先來看下類加載器的層次關(guān)系圖,如下:

啟動類加載器(Bootstrap ClassLoader),負責加載存放在$JAVA_HOME\jre\lib下,或被-Xbootclasspath參數(shù)指定的路徑中的,并且能被虛擬機識別的類庫(如rt.jar,所有的java.*開頭的類均被Bootstrap ClassLoader加載)。啟動類加載器是無法被Java程序直接引用的。
擴展類加載器(Extension ClassLoader),該加載器由sun.misc.Launcher$ExtClassLoader實現(xiàn),它負責加載$JAVA_HOME\jre\lib\ext目錄中,或者由java.ext.dirs系統(tǒng)變量指定的路徑中的所有類庫(如javax.*開頭的類),開發(fā)者可以直接使用擴展類加載器。
應用程序類加載器(Application ClassLoader),該類加載器由sun.misc.Launcher$AppClassLoader來實現(xiàn),它負責加載用戶類路徑(ClassPath)所指定的類,開發(fā)者可以直接使用該類加載器,如果應用程序中沒有自定義過自己的類加載器,一般情況下這個就是程序中默認的類加載器。
自定義類加載器(User ClassLoader),如果有必要,我們還可以加入自定義的類加載器。因為JVM自帶的ClassLoader只是懂得從本地文件系統(tǒng)加載標準的java class文件。
雙親委派機制是指如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把請求委托給父加載器去完成,依次向上,因此,所有的類加載請求最終都應該被傳遞到頂層的啟動類加載器中,只有當父加載器在它的搜索范圍中沒有找到所需的類時,即無法完成該加載,子加載器才會嘗試自己去加載該類。
為了更清楚的了解雙親委派機制,我們來看下jdk1.8源碼java.lang.ClassLoader.loadClass()方法實現(xiàn):
? ??
上面代碼注釋寫的很清楚,首先調(diào)用findLoadedClass方法檢查是否已加載過這個類,如果沒有就調(diào)用parent的loadClass方法,從底層一級級往上。如果所有ClassLoader都沒有加載過這個類,就調(diào)用findClass方法查找這個類,然后又從頂層逐級向下調(diào)用findClass方法,最終都沒找到就拋出ClassNotFoundException。這樣設計的目的是保證安全性,防止系統(tǒng)類被偽造。
為了便于理解,以下是加載邏輯示意圖:

本文章對應的視頻講解? ?https://www.bilibili.com/video/BV1UX4y1r7mA/