Java 程序包含很多類文件,每一個都與單個Java類相對應,這些類文件不像靜態C程序,一次性加載入內存,它們隨時需要隨時加載。這就是類加載器與眾不同的地 方。它從源文件(通常是.class 或 .jar文件)獲得不依賴平臺的字節碼,然后將它們加載到JVM內存空間,所以它們能被解釋和執行。默認狀態下,應用程序的每個類由 java.lang.ClassLoader加載。因為它可以被繼承,所以可以自由地加強其功能。
使用自定義類加載器的原因
默認的 java.lang.ClassLoader僅僅可以從加載本地文件系統的類。Java被設計成不論本地磁盤或網絡都有足夠的彈性加載類,并且可以在加載 之前處理特殊事物。例如:應用程序可以檢查Web站點或FTP上插入類的更新版本并且自動校驗數字簽名確保執行可信任的代碼。許多眾所周知的軟件都使用自 己的類加載器。
通常默認加載器是所謂的bootstrap類加載器;它負責加載諸如java.lang.Object等關鍵類和加 載其他rt.jar文件的運行時代碼到內存。因為Java語言規范沒有提供bootstrap類加載器的詳細信息,不同的JVM可能有不同的類加載器。如 果看到網頁上有applets在運行,則它使用的是自定義類加載器。嵌入到瀏覽器中的applet閱讀器包含了可以訪問遠程服務器上站點的類加載器,它可 以通過HTTP加載原始字節碼文件,并且在JVM中將它們轉換成類。
類加載器(除了bootstrap類加載器)有父類加載器,這些父類是基本加載器的加載器實例。最重要的一點是設置正確的父加載器。然后可以使用 類加載器的getParent()方法實現委派類請求(例如:自定義類加載器找不到使用專門方法的類時)。此時必須為將父加載器作為 java.lang.ClassLoader構造器的參數:public class MyClassLoader extends ClassLoader
{
public MyClassLoader()
{
super(MyClassLoader.class.getClassLoader());
}
}
loadClass(String name)方法是ClassLoader的入口。名字參數是完全資格類名(FQCN),例如關于包類名。如果父加載器設置正確,當請求 MyClassLoader中的loadClass(String name)方法加載類,但又找不到需要加載的類時,則首先會詢問父加載器。如果父加載器也找不到此類,則調用findClass(String name)方法。默認狀態下findClass(String name)會拋出ClassNotFoundException例外,很多開發人員都很清楚這個例外。自定義類加載器的開發者都希望從 java.lang.ClassLoader繼承時跳過這個方法。
findClass()方法的目標是為MyClassLoader容納所有專門代碼,此時不需要重復其他代碼(例如當加載失敗時調用系統 ClassLoader)。在此方法中,ClassLoader需要從原文件中獲取字節碼。一旦找到字節碼則會調用defineClass()方法。 ClassLoader實例調用此方法是非常重要的。因此,如果兩個ClassLoader實例定義了來自不同或相同原文件的字節碼,則被定義的類也將區 別對待。
我們給出兩個相似的類加載器MyClassLoader1 和 MyClassLoader2,它們都可以從相同的源文件找到MyCoolClass字節碼。如果一個程序通過這兩個加載器分別獨立加載 MyCoolClass實例(coolClass1通過MyClassLoader1加載, coolClass2通過MyClassLoader2加載),MyCoolClass.class能夠被獨立定義。執行下面的代碼:
MyCoolClass coolClass1 = (MyCoolClass)coolClass2;
將得到一個ClassCastException例外。(開發者如果沒有很好的理解類加載機制則經常碰到這樣的情況。)因為它們是不同的加載器 所定義的,JVM將它們看成不同的類。雖然它們是相同類型的類并且從相同的源文件加載,但是變量coolClass1和coolClass2不兼容。
不論是否跳過findClass() 或 loadClass(),getSystemClassLoader()方法將以實際ClassLoader對象的形式直接訪問系統 ClassLoader。也可以通過調用findSystemClass(String name)方法間接訪問。getParent()方法允許獲得父加載器。 Listing A 給出了可以運行的自定義類加載器示例。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
