對(duì)于java類加載器的認(rèn)識(shí)(2)
讓我們先回到j(luò)ava的動(dòng)態(tài)性,實(shí)現(xiàn)java的動(dòng)態(tài)性有兩種方法類型:一種是隱式,另一種是顯式。什么是隱式?new 這個(gè)關(guān)鍵字我們都認(rèn)識(shí),當(dāng)我們用其將類實(shí)例化時(shí)(即將對(duì)象載入),這種就是隱式!我們?cè)賮砜达@式的實(shí)現(xiàn)方法,一種可以由java.long.Class里面的forName()方法將類實(shí)例化,其中也用到了類加載器,詳情見:認(rèn)識(shí)java的Class類,另一種是由也就是直接用類加載器ClassLoader來實(shí)現(xiàn)。ClassLoader一些重要的方法
A) 方法 loadClass
ClassLoader.loadClass() 是 ClassLoader 的入口點(diǎn)。該方法的定義如下:
Class loadClass( String name, boolean resolve );
參數(shù)name JVM 需要的類的名稱,如 Person 或 java.lang.Object。
參數(shù) resolve 參數(shù)告訴方法是否需要解析類。在準(zhǔn)備執(zhí)行類之前,應(yīng)考慮類解析。并不總是需要解析。如果 JVM 只需要知道該類是否存在或找出該類的超類,那么就不需要解析詳情見:認(rèn)識(shí)java的Class類 中的forName()方法的介紹。
B) 方法 defineClass
defineClass 方法是 ClassLoader 的主要訣竅。該方法接受由原始字節(jié)組成的數(shù)組并把它轉(zhuǎn)換成 Class 對(duì)象。原始數(shù)組包含如從文件系統(tǒng)或網(wǎng)絡(luò)裝入的數(shù)據(jù)。defineClass 管理 JVM 的許多復(fù)雜、神秘和倚賴于實(shí)現(xiàn)的方面 -- 它把字節(jié)碼分析成運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)、校驗(yàn)有效性等等。不必?fù)?dān)心,您無需親自編寫它。事實(shí)上,即使您想要這么做也不能覆蓋它,因?yàn)樗驯粯?biāo)記成final的。
C) 方法 findSystemClass
findSystemClass 方法從本地文件系統(tǒng)裝入文件。它在本地文件系統(tǒng)中尋找類文件,如果存在,就使用 defineClass 將原始字節(jié)轉(zhuǎn)換成 Class 對(duì)象,以將該文件轉(zhuǎn)換成類。當(dāng)運(yùn)行 Java 應(yīng)用程序時(shí),這是 JVM 正常裝入類的缺省機(jī)制。(Java 2 中 ClassLoader 的變動(dòng)提供了關(guān)于 Java 版本 1.2 這個(gè)過程變動(dòng)的詳細(xì)信息。) 對(duì)于定制的 ClassLoader,只有在嘗試其它方法裝入類之后,再使用 findSystemClass。原因很簡單:ClassLoader 是負(fù)責(zé)執(zhí)行裝入類的特殊步驟,不是負(fù)責(zé)所有類。例如,即使 ClassLoader 從遠(yuǎn)程的 Web 站點(diǎn)裝入了某些類,仍然需要在本地機(jī)器上裝入大量的基本 Java 庫。而這些類不是我們所關(guān)心的,所以要 JVM 以缺省方式裝入它們:從本地文件系統(tǒng)。這就是 findSystemClass 的用途。
D) 方法 resolveClass
正如前面所提到的,可以不完全地(不帶解析)裝入類,也可以完全地(帶解析)裝入類。當(dāng)編寫我們自己的 loadClass 時(shí),可以調(diào)用 resolveClass,這取決于 loadClass 的 resolve 參數(shù)的值。
E) 方法 findLoadedClass
findLoadedClass 充當(dāng)一個(gè)緩存:當(dāng)請(qǐng)求 loadClass 裝入類時(shí),它調(diào)用該方法來查看 ClassLoader 是否已裝入這個(gè)類,這樣可以避免重新裝入已存在類所造成的麻煩。應(yīng)首先調(diào)用該方法。
怎么組裝這些方法
1) 調(diào)用 findLoadedClass 來查看是否存在已裝入的類。
2) 如果沒有,那么采用那種特殊的神奇方式來獲取原始字節(jié)。
3) 如果已有原始字節(jié),調(diào)用 defineClass 將它們轉(zhuǎn)換成 Class 對(duì)象。
4) 如果沒有原始字節(jié),然后調(diào)用 findSystemClass 查看是否從本地文件系統(tǒng)獲取類。
5) 如果 resolve 參數(shù)是 true,那么調(diào)用 resolveClass 解析 Class 對(duì)象。
6) 如果還沒有類,返回 ClassNotFoundException。
Java 2 中 ClassLoader 的變動(dòng)
1)loadClass 的缺省實(shí)現(xiàn)
定制編寫的 loadClass 方法一般嘗試幾種方式來裝入所請(qǐng)求的類,如果您編寫許多類,會(huì)發(fā)現(xiàn)一次次地在相同的、很復(fù)雜的方法上編寫變量。 在 Java 1.2 中 loadClass 的實(shí)現(xiàn)嵌入了大多數(shù)查找類的一般方法,并使您通過覆蓋 findClass 方法來定制它,在適當(dāng)?shù)臅r(shí)候 findClass 會(huì)調(diào)用 loadClass。 這種方式的好處是您可能不一定要覆蓋 loadClass;只要覆蓋 findClass 就行了,這減少了工作量。
2)新方法:findClass
loadClass 的缺省實(shí)現(xiàn)調(diào)用這個(gè)新方法。findClass 的用途包含您的 ClassLoader 的所有特殊代碼,而無需要復(fù)制其它代碼(例如,當(dāng)專門的方法失敗時(shí),調(diào)用系統(tǒng) ClassLoader)。
3) 新方法:getSystemClassLoader
如果覆蓋 findClass 或 loadClass,getSystemClassLoader 使您能以實(shí)際 ClassLoader 對(duì)象來訪問系統(tǒng) ClassLoader(而不是固定的從 findSystemClass 調(diào)用它)。
4) 新方法:getParent
為了將類請(qǐng)求委托給父代 ClassLoader,這個(gè)新方法允許 ClassLoader 獲取它的父代 ClassLoader。當(dāng)使用特殊方法,定制的 ClassLoader 不能找到類時(shí),可以使用這種方法。
父代 ClassLoader 被定義成創(chuàng)建該 ClassLoader 所包含代碼的對(duì)象的 ClassLoader。
posted on 2005-11-24 18:40 早餐2塊2 閱讀(905) 評(píng)論(0) 編輯 收藏 所屬分類: java基礎(chǔ)