華文網

Java中的轉換器——類載入器(ClassLoader)

開發過程中可能不需要瞭解類載入器,也能正常編寫代碼,但我們在處理一些代碼問題時,就需要瞭解類載入器的知識,只有這樣才能找到問題的本質;不管學習什麼底層原理都是學習的重點。

下面一起學習類載入器(ClassLoader)相關知識。

網路配圖

首先,類載入器(ClassLoader)是什麼,Java程式的運行與其他程式不同,Java程式(class檔)一開始並不是本地可執行檔;當運行Java程式時,先要運行JVM(Java虛擬機器),然後再把Java class載入到JVM裡頭運行,負責載入Java class的這部分就叫做類載入器(ClassLoader)。

JVM本身包含了一個ClassLoader稱為Bootstrap ClassLoader,和JVM一樣,Bootstrap ClassLoader是用本地代碼實現的,它負責載入核心Java Class(即所有java.*開頭的類);另外JVM還會提供兩個ClassLoader,它們都是用Java語言編寫的,由Bootstrap ClassLoader載入;其中Extension ClassLoader負責載入擴展的Java class(例如所有javax.*開頭的類和存放在JRE的ext目錄下的類),Application ClassLoader負責載入應用程式自身的類。

其次,什麼時候ClassLoader會載入類,當你使用java去執行一個類,JVM使用Application ClassLoader載入這個類;然後如果類A引用了類B,不管是直接引用還是用Class.forName()引用,JVM就會找到載入類A的ClassLoader,

並用這個ClassLoader來載入類B。

網路配圖

因為JVM自帶的ClassLoader只會從本地檔案系統載入標準的java class檔,如果我們編寫自己的ClassLoader,就可以做到:

(1)、在執行非置信代碼之前,自動驗證數位簽章;

(2)、動態地創建符合使用者特定需要的定制化構建類;

(3)、從特定的場所取得java class,例如從資料庫中;

目前的大部分應用伺服器都使用了ClassLoader技術,即使我們不需要創建自己的ClassLoader,瞭解其原理也有助於更好地部署自己的應用到伺服器。

如何創建一個ClassLoader?創建自己的ClassLoader時,需要繼承java.lang.ClassLoader或者它的子類。在產生實體每個ClassLoader物件時,需要指定一個父物件;如果沒有指定的話,系統自動指定ClassLoader.getSystemClassLoader()為父物件。

Java Class的載入採用所謂的委託模式(Delegation Modle),當調用一個ClassLoader.loadClass()載入一個類的時候,將遵循以下的步驟:

檢查這個類是否已經被載入進來了;

如果還沒有載入,調用父物件載入該類;

如果父物件無法載入,調用本物件的findClass()取得這個類;

所以當創建自己的Class Loader時,只需要重載findClass()這個方法。

網路配圖

通常程式發佈後,部分功能有優化完善或修復Bug後如何更新已經被載入了的類進而更新應用的功能呢?JSP是一個非常典型的例子,

如果一個JSP檔被更改了,應用伺服器則需要把更改後的JSP重新編譯,然後載入新生成的類來回應後繼的請求;其實一個已經載入的類是無法被更新的,如果你試圖用同一個ClassLoader再次載入同一個類,就會得到異常(java.lang.LinkageError: duplicate class definition),我們只能夠重新創建一個新的ClassLoader實例來再次載入新類。

最後,學習一下類載入的形式;類載入無非就是以下三種方式:

class A{}

class B{}

class C{}

public class Loader{

public static void main(String[] args) throws Exception{

Class aa=A.class;

Class bb=Class.forName("B");

Class cc=ClassLoader.getSystemClassLoader().loadClass("C");

}

}

好了,今天先學習這麼多,深層次的東西將在後續文章中學習!!!

class A{}

class B{}

class C{}

public class Loader{

public static void main(String[] args) throws Exception{

Class aa=A.class;

Class bb=Class.forName("B");

Class cc=ClassLoader.getSystemClassLoader().loadClass("C");

}

}

好了,今天先學習這麼多,深層次的東西將在後續文章中學習!!!