介紹
注意類加載器的體系并不是“繼承”體系,而是一個“委派”體系。大多數(shù)類加載器首先會到自己的 parent 中查找類或者資源,如果找不到,才會在自己的本地進行查找。事實上,類加載器被定義加載那些在 parent 中無法加載到的類。
先大體了解一下 classloader 的 API
package java.lang;
public abstract class ClassLoader {
public Class loadClass(String name);
protected Class defineClass(byte[] b);
public ClassLoader getParent();
public URL getResource(String name);
public Enumeration getResources(String name);
}
ClassLoader分類
- BootStrap ClassLoader
稱為啟動類加載器,是 Java 類加載層次中最頂層的類加載器,負(fù)責(zé)加載 JDK 中的核心類庫,如:rt.jar、resources.jar、charsets.jar等。
目錄為$JAVA_HOME/jre/classes或者使用如下配置 JVM 參數(shù)
-Xbootclasspath:<用:分隔的目錄和zip/jar文件>
設(shè)置搜索路徑以引導(dǎo)類和資源
-Xbootclasspath/a:<用:分隔的目錄和zip/jar文件>
附加在引導(dǎo)類路徑末尾
-Xbootclasspath/p:<用:分隔的目錄和zip/jar文件>
置于引導(dǎo)類路徑之前
- Extension ClassLoader
稱為擴展類加載器,負(fù)責(zé)加載 Java 的擴展類庫,默認(rèn)加載 JAVA_HOME/jre/lib/ext 目錄下的所有 jar。
目錄為 $JAVA_HOME/jre/lib/ext
-
App ClassLoader
稱為系統(tǒng)類加載器,負(fù)責(zé)加載應(yīng)用程序 classpath 目錄下的所有 jar 和 class 文件。
除了 Java 默認(rèn)提供的三個 ClassLoader 之外,用戶還可以根據(jù)需要定義自已的 ClassLoader,而這些自定義的 ClassLoader 都必須繼承自 java.lang.ClassLoader 類,ExtensionClassLoader 和 AppClassLoader 也是繼承自 java.lang.ClassLoader 類,但是 BootstrapClassLoader 沒有繼承ClassLoader,因為它不是一個普通的 Java 類,底層由 C++ 編寫,已嵌入到了 JVM 內(nèi)核當(dāng)中,當(dāng) JVM 啟動后,BootstrapClassLoader 也隨著啟動,負(fù)責(zé)加載完核心類庫后,并構(gòu)造 ExtensionClassLoader 和 AppClassLoader 類加載器。
自定義ClassLoader
因為 Java 中提供的默認(rèn) ClassLoader,只加載指定目錄下的 jar 和 class ,如果我們想加載其它位置的類或 jar 時,默認(rèn)的 ClassLoader 就不能滿足我們的需求了,所以需要定義自己的 ClassLoader。
定義自已的類加載器分為兩步:
- 繼承 java.lang.ClassLoader
- 重寫父類的 findClass 方法