一、Java ClassLoader
1,什么是ClassLoader
與 C 或 C++ 編寫的程序不同,Java 程序并不是一個(gè)可執(zhí)行文件,而是由許多獨(dú)立的類文件組成,每一個(gè)文件對(duì)應(yīng)于一個(gè) Java 類。
此外,這些類文件并非立即全部都裝入內(nèi)存,而是根據(jù)程序需要裝入內(nèi)存。ClassLoader 是 JVM 中將類裝入內(nèi)存的那部分。
而且,Java ClassLoader 就是用 Java 語(yǔ)言編寫的。這意味著創(chuàng)建您自己的 ClassLoader 非常容易,不必了解 JVM 的微小細(xì)節(jié)。
2,一些重要的方法
A)loadClass
ClassLoader.loadClass() 是ClassLoader的入口點(diǎn)。該方法的定義為:Class loadClass( String name, boolean resolve );
name:JVM 需要的類的名稱,如 Foo 或 java.lang.Object。
resolve:參數(shù)告訴方法是否需要解析類。
B)defineClass
defineClass方法是ClassLoader的主要訣竅。該方法接受由原始字節(jié)組成的數(shù)組并把它轉(zhuǎn)換成Class對(duì)象。
C)findSystemClass
findSystemClass方法從本地文件系統(tǒng)中尋找類文件,如果存在,就使用defineClass將原始字節(jié)轉(zhuǎn)換成Class對(duì)象,以將該文件轉(zhuǎn)換成類。
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)用該方法來(lái)查看ClassLoader是否已裝入這個(gè)類,這樣可以避免重新裝入已存在類所造成的麻煩。
3,Java2中ClassLoader的變動(dòng)
1)loadClass的缺省實(shí)現(xiàn)
在Java2中l(wèi)oadClass的實(shí)現(xiàn)嵌入了大多數(shù)查找類的一般方法,并使您通過覆蓋findClass方法來(lái)定制它,在適當(dāng)?shù)臅r(shí)候findClass會(huì)調(diào)用loadClass。
這種方式的好處是可能不一定要覆蓋loadClass,只要覆蓋findClass就行了,這減少了工作量。
2)新方法:findClass
loadClass的缺省實(shí)現(xiàn)調(diào)用這個(gè)新方法。
3)新方法:getSystemClassLoader
如果覆蓋findClass或loadClass,getSystemClassLoader讓我們以實(shí)際ClassLoader對(duì)象來(lái)訪問系統(tǒng)ClassLoader,而不是固定的從findSystemClass 調(diào)用它。
4)新方法:getParent
為了將類請(qǐng)求委托給父ClassLoader,這個(gè)新方法允許ClassLoader獲取它的父ClassLoader。
4,定制ClassLoader
其實(shí)我們或多或少都使用過定制的ClassLoader,因?yàn)锳pplet查看器中就包含一個(gè)定制的ClassLoader。
它不在本地文件系統(tǒng)中尋找類,而是訪問遠(yuǎn)程服務(wù)器上的 Web 站點(diǎn),經(jīng)過 HTTP 裝入原始的字節(jié)碼文件,并把它們轉(zhuǎn)換成JVM 內(nèi)的類。
Applet查看器中的ClassLoader還可以做其它事情:它們支持安全性以及使不同的Applet在不同的頁(yè)面上運(yùn)行而互不干擾。
我們將寫一個(gè)自己的ClassLoader實(shí)現(xiàn)示例,它將實(shí)現(xiàn)如下步驟,這也是ClassLoader的工作原理:
# 調(diào)用 findLoadedClass 來(lái)查看是否存在已裝入的類。
# 如果沒有,那么采用那種特殊的神奇方式來(lái)獲取原始字節(jié)。
# 如果已有原始字節(jié),調(diào)用defineClass將它們轉(zhuǎn)換成Class對(duì)象。
# 如果沒有原始字節(jié),然后調(diào)用findSystemClass查看是否從本地文件系統(tǒng)獲取類。
# 如果resolve參數(shù)是true,那么調(diào)用resolveClass解析Class對(duì)象。
# 如果還沒有類,返回ClassNotFoundException。
# 否則,將類返回給調(diào)用程序。
話不多說(shuō),看看代碼先:
FileClassLoader.java:

2

3

4

5

6



7



8

9

10

11

12



13

14

15



16

17

18

19



20

21

22

23



24

25

26

27

28

29

MyApp.java:















編譯并運(yùn)行MyApp類,結(jié)果為:



