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