開始正式我們的ClassLoader總結(jié)分析蜕依。
ClassLoader的分類(Hot Spot JVM):
- BootStrap ClassLoader(啟動類加載器)
- Extension ClassLoader(擴(kuò)展類加載器)
- Application ClassLoader(應(yīng)用程序類加載器)
- User ClassLoader(用戶自己實(shí)現(xiàn)的加載器)
BootStrap ClassLoader
C++實(shí)現(xiàn)蝶糯。加載JVM自身需要的類,負(fù)責(zé)將{JAVA_HOME}/lib路徑下的核心類庫或者-Xbootclasspath指定的路徑下的jar包加載到內(nèi)存中划乖。說到這我就有個問題贬养,那我們可不可以將jar包直接丟進(jìn)對應(yīng)的路徑下,讓BootStrap ClassLoader自動幫我們進(jìn)行加載呢琴庵?應(yīng)該是不行的误算,為什么呢?因?yàn)锽ootStrap ClassLoader是根據(jù)文件名進(jìn)行匹配加載迷殿,也就是說儿礼,它只加載包名為java、javax庆寺、sun等開頭的類蚊夫。
Extension ClassLoader
Java實(shí)現(xiàn)。負(fù)責(zé)加載<JAVA_HOME>/lib/ext目錄下面或者系統(tǒng)變量-Djava.ext.dir指定路徑中的類止邮。
源代碼如下所示:
//ExtClassLoader類中獲取路徑的代碼
private static File[] getExtDirs() {
//加載<JAVA_HOME>/lib/ext目錄中的類庫
String s = System.getProperty("java.ext.dirs");
File[] dirs;
if (s != null) {
StringTokenizer st =
new StringTokenizer(s, File.pathSeparator);
int count = st.countTokens();
dirs = new File[count];
for (int i = 0; i < count; i++) {
dirs[i] = new File(st.nextToken());
}
} else {
dirs = new File[0];
}
return dirs;
}
Application ClassLoader
主要負(fù)責(zé)加載java -classpath或者-D java.class.path底下的類庫这橙。他也是跟我程序員打交道最多的類加載器。
雙親委派模式
工作原理
從圖中我們可以看出來导披,當(dāng)一個類加載器收到了需要加載請求的時候屈扎,并不會自己先去加載,而是將任務(wù)丟給它的父類撩匕,當(dāng)父類還有父類的時候鹰晨,繼續(xù)重復(fù)上一次的操作,倘若父類加載器無法完成加載任務(wù)止毕,這個時候子類才會進(jìn)行嘗試加載模蜡。這就是雙親委派模型,簡稱坑爹模型扁凛。
為什么要這樣子做呢忍疾?
1.可以避免類的重復(fù)加載,當(dāng)父類已經(jīng)加載了該類的時候谨朝,子類就沒有必要進(jìn)行重復(fù)加載了卤妒。
2.安全原因,假設(shè)你想要加載一個自定義的java.lang.String類的話字币,當(dāng)雙親委派模型找到了頂層加載器则披,發(fā)現(xiàn)在核心API中已經(jīng)定義了當(dāng)前類,就不會在此加載此類洗出,防止api被篡改士复。