開始正式我們的ClassLoader總結(jié)分析。
ClassLoader的分類(Hot Spot JVM):
- BootStrap ClassLoader(啟動(dòng)類加載器)
- 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)存中。說到這我就有個(gè)問題,那我們可不可以將jar包直接丟進(jìn)對應(yīng)的路徑下,讓BootStrap ClassLoader自動(dòng)幫我們進(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)一個(gè)類加載器收到了需要加載請求的時(shí)候,并不會(huì)自己先去加載,而是將任務(wù)丟給它的父類,當(dāng)父類還有父類的時(shí)候,繼續(xù)重復(fù)上一次的操作,倘若父類加載器無法完成加載任務(wù),這個(gè)時(shí)候子類才會(huì)進(jìn)行嘗試加載。這就是雙親委派模型,簡稱坑爹模型。
為什么要這樣子做呢?
1.可以避免類的重復(fù)加載,當(dāng)父類已經(jīng)加載了該類的時(shí)候,子類就沒有必要進(jìn)行重復(fù)加載了。
2.安全原因,假設(shè)你想要加載一個(gè)自定義的java.lang.String類的話,當(dāng)雙親委派模型找到了頂層加載器,發(fā)現(xiàn)在核心API中已經(jīng)定義了當(dāng)前類,就不會(huì)在此加載此類,防止api被篡改。