更新時間:2022-07-18 12:44:31 來源:動力節點 瀏覽2326次
Java 類加載器是Java 運行時環境的一部分,它可以將 Java 類動態加載到Java 虛擬機中。由于類加載器,Java 運行時系統不需要了解文件和文件系統。
Java 類不會一次全部加載到內存中,而是在應用程序需要時加載。此時,JRE調用Java ClassLoader,這些 ClassLoader 將類動態加載到內存中。
并非所有類都由單個 ClassLoader 加載。根據類的類型和類的路徑,決定加載該特定類的 ClassLoader。要了解加載類的 ClassLoader,請使用getClassLoader()方法。所有類都根據它們的名稱加載,如果找不到這些類中的任何一個,則返回NoClassDefFoundError或ClassNotFoundException。
Java 類加載器分為三種類型:
BootStrap ClassLoader:Bootstrap ClassLoader是一個機器代碼,它在 JVM 調用它時啟動操作。它不是一個java類。它的工作是加載第一個純Java ClassLoader。Bootstrap ClassLoader 從rt.jar位置加載類。Bootstrap ClassLoader 沒有任何父 ClassLoader。它也被稱為Primodial ClassLoader。
Extension ClassLoader: Extension ClassLoader 是 Bootstrap ClassLoader 的子類,從各自的 JDK Extension 庫中加載核心 java 類的擴展。它從jre/lib/ext目錄或系統屬性java.ext.dirs指向的任何其他目錄加載文件。
系統類加載器:應用程序類加載器也稱為系統類加載器。它加載在環境變量CLASSPATH、-classpath 或 -cp 命令行選項中找到的應用程序類型類。Application ClassLoader 是 Extension ClassLoader 的子類。
注意:ClassLoader 委托層次模型總是按照 Application ClassLoader->Extension ClassLoader->Bootstrap ClassLoader 的順序運行。Bootstrap ClassLoader 總是被賦予更高的優先級,其次是 Extension ClassLoader,然后是 Application ClassLoader。
功能原則是Java 類加載器工作的一組規則或特性。功能的三個原則,它們是:
委托模型:Java 虛擬機和 Java 類加載器使用一種稱為委托層次算法的算法將類加載到 Java 文件中。
ClassLoader 基于委托模型給出的一組操作工作。他們是:
ClassLoader 始終遵循委托層次原則。
每當 JVM 遇到一個類時,它都會檢查該類是否已經加載。
如果該類已經加載到方法區域中,則 JVM 繼續執行。
如果該類不在方法區域中,則 JVM 要求 Java ClassLoader Sub-System 加載該特定類,然后 ClassLoader 子系統將控制權移交給Application ClassLoader。
然后,Application ClassLoader 將請求委托給 Extension ClassLoader,而Extension ClassLoader又將請求委托給Bootstrap ClassLoader。
Bootstrap ClassLoader 將在 Bootstrap 類路徑(JDK/JRE/LIB)中搜索。如果類可用,則加載它,否則將請求委托給 Extension ClassLoader。
Extension ClassLoader 在 Extension Classpath(JDK/JRE/LIB/EXT) 中搜索類。如果類可用,則加載它,否則將請求委托給 Application ClassLoader。
Application ClassLoader 在 Application Classpath 中搜索類。如果該類可用,則加載它,如果不可用,則生成ClassNotFoundException異常。
可見性原則:可見性原則指出,由父類加載器加載的類對子類加載器可見,但由子類加載器加載的類對父類加載器不可見。假設一個類 GEEKS.class 已被 Extension ClassLoader 加載,那么該類僅對 Extension ClassLoader 和 Application ClassLoader 可見,而對 Bootstrap ClassLoader 不可見。如果再次嘗試使用 Bootstrap ClassLoader 加載該類,則會給出異常java.lang.ClassNotFoundException。
唯一性屬性:唯一性屬性確保類是唯一的并且沒有類的重復。這也確保了父類加載器加載的類不會被子類加載器加載。如果父類加載器無法找到該類,那么只有當前實例會嘗試自己這樣做。
在 JVM 請求類之后,需要執行幾個步驟來加載類。類是根據委托模型加載的,但有一些重要的方法或函數在加載類中起著至關重要的作用。
loadClass(String name, boolean resolve):該方法用于加載JVM引用的類。它將類的名稱作為參數。這是 loadClass(String, boolean) 類型。
defineClass():defineClass() 方法是最終方法,不能被覆蓋。此方法用于將字節數組定義為類的實例。如果類無效,則拋出ClassFormatError。
findClass(String name):此方法用于查找指定的類。此方法只查找但不加載類。
findLoadedClass(String name):該方法用于驗證 JVM 引用的 Class 之前是否已加載。
Class.forName(String name, boolean initialize, ClassLoader loader):該方法用于加載類以及初始化類。此方法還提供了選擇任何一個 ClassLoader 的選項。如果 ClassLoader 參數為 NULL,則使用 Bootstrap ClassLoader。
示例:在加載類之前執行以下代碼:
protected synchronized Class<?>
loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
Class c = findLoadedClass(name);
try {
if (c == NULL) {
if (parent != NULL) {
c = parent.loadClass(name, false);
}
else {
c = findBootstrapClass0(name);
}
}
catch (ClassNotFoundException e)
{
System.out.println(e);
}
}
}
注意:如果一個類已經被加載,它會返回它。否則,它將對新類的搜索委托給父類加載器。如果父類加載器沒有找到該類,loadClass()調用方法findClass()來查找并加載該類。如果父ClassLoader沒有找到該類, findClass()方法會在當前ClassLoader中搜索該類。如果大家想了解更多相關知識,不妨來關注一下動力節點的Java在線學習,里面的課程內容從入門到精通,很適合零基礎的小伙伴學習,希望對大家能夠有所幫助。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習