什么是 ClassLoader?
??????
????? 在流行的商業化編程語言中,Java 語言由于在 Java 虛擬機 (JVM) 上運行而顯得與眾不同。這意味著已編譯的程序是一種特殊的、獨立于平臺的格式,并非依賴于它們所運行的機器。在很大程度上,這種格式不同于傳統的可執行程序格式。
與 C 或 C++ 編寫的程序不同,Java 程序并不是一個可執行文件,而是由許多獨立的類文件組成,每一個文件對應于一個 Java 類。
此外,這些類文件并非立即全部都裝入內存,而是根據程序需要裝入內存。ClassLoader 是 JVM 中將類裝入內存的那部分。
而且,Java ClassLoader 就是用 Java 語言編寫的。這意味著創建您自己的 ClassLoader 非常容易,不必了解 JVM 的微小細節。
???? java得classloader 不但可以使你運行本地得class類,你也可以定制classloader運行來自遠程的字節代碼.?????
??? ClassLoader 的基本目標是對類的請求提供服務。當 JVM 需要使用類時,它根據名稱向 ClassLoader 請求這個類,然后 ClassLoader 試圖返回一個表示這個類的 Class
對象。
通過覆蓋對應于這個過程不同階段的方法,可以創建定制的 ClassLoader。
??? 通常當你需要動態加載資源的時候, 你至少有三個ClassLoader可以選擇:
2???????
系統類加載器或叫作應用類加載器
(system classloader or application classloader)
2???????
當前類加載器
2???????
當前線程類加載器
第一種:系統類加載器
????系統類加載器(system classloader). 這個類加載器處理-classpath下的類加載工作, 可以通過ClassLoader.getSystemClassLoader()方法調用. ClassLoader下所有的getSystemXXX()的靜態方法都是通過這個方法定義的. 在你的代碼中, 你應該盡量少地調用這個方法,以其它的類加載器作為代理. 否則你的代碼將只能工作在簡單的命令行應用中, 這個時候系統類加載器(system classloader)是JVM最后創建的類加載器. 一但你把代碼移到EJB, Web應用或Java Web Start應用中, 一定會出問題?.
Class.loadClass( String name, boolean resolve );
?????? name
參數指定了 JVM 需要的類的名稱,該名稱以包表示法表示,如 Foo
或 ?java.lang.Object
。
?????? resolve
參數告訴方法是否需要解析類。在準備執行類之前,應考慮類解析。并不總是需要解析。如果 JVM 只需要知道該類是否存在或找出該類的超類,那么就不需要解析。
????
????? defineClass
方法是 ClassLoader 的主要訣竅。該方法接受由原始字節組成的數組并把它轉換成 Class
對象。原始數組包含如從文件系統或網絡裝入的數據。
defineClass
管理 JVM 的許多復雜、神秘和倚賴于實現的方面 -- 它把字節碼分析成運行時數據結構、校驗有效性等等。不必擔心,您無需親自編寫它。事實上,即使您想要這么做也不能覆蓋它,因為它已被標記成最終的。
?? 方法 findSystemClass
?? findSystemClass 方法從本地文件系統裝入文件。它在本地文件系統中尋找類文件,如果存在,就使用 defineClass
將原始字節轉換成 Class
對象,以將該文件轉換成類。當運行 Java 應用程序時,這是 JVM 正常裝入類的缺省機制.
?? 如果 ClassLoader 不能找到類,它會請求父代 ClassLoader 來執行此項任務。所有 ClassLoaders 的根是系統 ClassLoader,它會以缺省方式裝入類 -- 即,從本地文件系統。
???? findLoadedClass
充當一個緩存:當請求 loadClass
裝入類時,它調用該方法來查看 ClassLoader 是否已裝入這個類,這樣可以避免重新裝入已存在類所造成的麻煩。應首先調用該方法。
?????
讓我們看一下如何組裝所有方法。
我們的 loadClass
實現示例執行以下步驟。(這里,我們沒有指定生成類文件是采用了哪種技術 -- 它可以是從 Net 上裝入、或者從歸檔文件中提取、或者實時編譯。無論是哪一種,那是種特殊的神奇方式,使我們獲得了原始類文件字節。)
- 調用
findLoadedClass
來查看是否存在已裝入的類。
- 如果沒有,那么采用那種特殊的神奇方式來獲取原始字節。
- 如果已有原始字節,調用
defineClass
將它們轉換成 Class
對象。
- 如果沒有原始字節,然后調用
findSystemClass
查看是否從本地文件系統獲取類。
- 如果
resolve
參數是 true
,那么調用 resolveClass
解析 Class
對象。
- 如果還沒有類,返回
ClassNotFoundException
。
- 否則,將類返回給調用程序。
第二種選擇: 當前上下文環境下的類加載器.
????
根據定義
,
當前類加載器就是你當前方法所屬的類的加載器
.
在運行時類之間動態聯編
,
及調用
Class.forName,() Class.getResource()
等類似方法時
,
這個類加載器會被隱含地使用
.
posted on 2006-08-04 12:29
鄧兵野 閱讀(929)
評論(2) 編輯 收藏 所屬分類:
jdk技術