java類加載機制

ClassLoader 是一個抽象類。爲了擴充 [color=red]Java 虛擬機動態裝載類的方法[/color],應用程序可實現 ClassLoader 的繼承類。

通常,Java 虛擬機以與平臺有關的方式,從局部文件系統中裝載類。例如,在 UNIX 系統,虛擬機從 CLASSPATH 環境變量中定義的路徑中裝載類。

但是,

[color=red]某些類可能不是來自文件,而是來自其它資源,諸如網絡,或者它們可能是由應用程序創建的。 [/color]

[color=red]defineClass 方法將一字節數組轉換爲 Class 類的實例。採用 Class 類中的 newInstance 方法創建新定義的類的實例。[/color]

類裝載器創建的方法和構造子可以引用其它類。爲確定引用類,Java 虛擬機調用初始創建該類的類裝載器的 loadClass 方法。如果 Java 虛擬機僅需確定此類是否存在,和如果存在則如何獲知它的父類,那麼將 resolve 標記設爲 false。但是,如果該類的實例已創建,或它的方法已被調用,則必須解析該類。這種情況,resolve 標記設爲 true,調用 resolveClass 方法。

例如,一個應用程序能夠創建一網絡類裝載器,從某一個服務器上下載類文件。代碼可能如下:

[code]ClassLoader loader = new NetworkClassLoader(host, port);
Object main = loader.loadClass("Main", true).newInstance();
. . . [/code]網絡類裝載器的子類必須定義 loadClass 方法,實現從網上下載類。一旦已下載完該類,就應使用 defineClass方法,創建它的一個實例。實現示例如下:


[code]class NetworkClassLoader {
String host;
int port;
Hashtable cache = new Hashtable();
private byte loadClassData(String name)[] {
// load the class data from the connection
. . .
}
public synchronized Class loadClass(String name,
boolean resolve) {
Class c = cache.get(name);
if (c == null) {
byte data[] = loadClassData(name);
c = defineClass(data, 0, data.length);
cache.put(name, c);
}
if (resolve)
resolveClass(c);
return c;
}
}[/code]


Java的ClassLoader就是用來動態裝載class的,ClassLoader對一個class只會裝載一次,JVM使用的ClassLoader一共有4種:

啓動類裝載器,標準擴展類裝載器,類路徑裝載器和網絡類裝載器。

這4種ClassLoader的優先級依次從高到低,使用所謂的“雙親委派模型”。確切地說,如果一個網絡類裝載器被請求裝載一個java.lang.Integer,它會首先把請求發送給上一級的類路徑裝載器,如果返回已裝載,則網絡類裝載器將不會裝載這個java.lang.Integer,如果上一級的類路徑裝載器返回未裝載,它纔會裝載java.lang.Integer。

類似的,類路徑裝載器收到請求後(無論是直接請求裝載還是下一級的ClassLoader上傳的請求),它也會先把請求發送到上一級的標準擴展類裝載器,這樣一層一層上傳,於是啓動類裝載器優先級最高,如果它按照自己的方式找到了java.lang.Integer,則下面的ClassLoader都不能再裝載java.lang.Integer,儘管你自己寫了一個java.lang.Integer,試圖取代核心庫的java.lang.Integer是不可能的,因爲自己寫的這個類根本無法被下層的ClassLoader裝載。

再說說Package權限。Java語言規定,在同一個包中的class,如果沒有修飾符,默認爲Package權限,包內的class都可以訪問。但是這還不夠準確。

[color=red]確切的說,只有由同一個ClassLoader裝載的class才具有以上的Package權限。[/color]

[color=red]比如啓動類裝載器裝載了java.lang.String,類路徑裝載器裝載了我們自己寫的java.lang.Test,它們不能互相訪問對方具有Package權限的方法。[/color]

這樣就阻止了惡意代碼訪問核心類的Package權限方法。
發佈了0 篇原創文章 · 獲贊 0 · 訪問量 3058
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章