3分鐘了解Java雙親委派機(jī)制
作者丨Bob
來源丨IT爛筆頭
你得先知道
在介紹雙親委派機(jī)制的時(shí)候,不得不提ClassLoader。說ClassLoader之前,我們得先了解下Java的基本知識(shí)。
Java是運(yùn)行在Java的虛擬機(jī)(JVM)中的,但是它是怎么就運(yùn)行在JVM中了呢?我們?cè)贗DE中編寫的Java源代碼被編譯器編譯成.class的字節(jié)碼文件。然后由我們得ClassLoader負(fù)責(zé)將這些class問價(jià)加載到JVM中去執(zhí)行。
JVM中提供了三層的ClassLoader:
Bootstrap classLoader:主要負(fù)責(zé)加載核心的類庫(java.lang.*等),構(gòu)造ExtClassLoader和APPClassLoader。
ExtClassLoader:主要負(fù)責(zé)加載jre/lib/ext目錄下的一些擴(kuò)展的jar。
AppClassLoader:主要負(fù)責(zé)加載應(yīng)用程序的主函數(shù)類
那如果有一個(gè)Hello.class文件是如何被加載到JVM中的呢?
雙親委派機(jī)制
我打開了我的AndroidStudio,搜索了下“ClassLoader”,然后打開“java.lang”包下的ClassLoader類。然后將代碼翻到loadClass方法:
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
// -----????-----
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
return c;
}
其實(shí)這段代碼已經(jīng)很好的解釋了雙親委派機(jī)制,為了大家更容易理解,我做了一張圖來描述一下上面一段代碼到底是怎么做的:

從上圖中我們就更容易理解了,當(dāng)一個(gè)Hello.class這樣的文件要被加載時(shí)。不考慮我們自定義類加載器,首先會(huì)在AppClassLoader中檢查是否加載過,如果有那就無需再加載了。如果沒有,那么會(huì)拿到父加載器,然后調(diào)用父加載器的loadClass方法。父類中同理會(huì)先檢查自己是否已經(jīng)加載過,如果沒有再往上。注意這個(gè)過程,知道到達(dá)Bootstrap classLoader之前,都是沒有哪個(gè)加載器自己選擇加載的。如果父加載器無法加載,會(huì)下沉到子加載器去加載,一直到最底層,如果沒有任何加載器能加載,就會(huì)拋出ClassNotFoundException。
為什么要設(shè)計(jì)這種機(jī)制
這種設(shè)計(jì)有個(gè)好處是,如果有人想替換系統(tǒng)級(jí)別的類:String.java。篡改它的實(shí)現(xiàn),但是在這種機(jī)制下這些系統(tǒng)的類已經(jīng)被Bootstrap classLoader加載過了,所以并不會(huì)再去加載,從一定程度上防止了危險(xiǎn)代碼的植入。
-End-
最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!

面試題】即可獲取
