Java類加載器
此條目包含過多行話或專業術語,可能需要簡化或提出進一步解釋。 (2014年5月16日) |
Java類加載器(英語:Java Classloader)是Java運行時環境(Java Runtime Environment)的一個部件,負責動態加載Java類到Java虛擬機的內存空間中。[1]類通常是按需加載,即第一次使用該類時才加載。由於有了類加載器,Java運行時系統不需要知道文件與文件系統。對學習類加載器而言,掌握Java的委派概念是很重要的。
每個Java類必須由某個類加載器裝入到內存。[2]Java程序可以通過類加載器來利用外部庫(即由其他作者編寫的軟件庫)。
- 引導(Bootstrap)類加載器。由原生代碼(如C語言)編寫,不繼承自
java.lang.ClassLoader
。負責加載核心Java庫[5],存儲在<JAVA_HOME>/jre/lib
目錄中。 - 擴展(Extensions)類加載器。用來在
<JAVA_HOME>/jre/lib/ext
,[6]或java.ext.dirs
中指明的目錄中加載 Java的擴展庫。Java 虛擬機的實現會提供一個擴展庫目錄。該類加載器在此目錄裡面查找並加載 Java 類。該類由sun.misc.Launcher$ExtClassLoader
實現。 - Apps類加載器(也稱系統類加載器)。根據 Java應用程序的類路徑(
java.class.path
或CLASSPATH環境變量)來加載 Java 類。一般來說,Java 應用的類都是由它來完成加載的。可以通過 ClassLoader.getSystemClassLoader()來獲取它。該類由sun.misc.Launcher$AppClassLoader
實現。
每個類裝載器通過組合的方式包含一個父裝載器(parent class loader)。
JDK 1.2之後引入「雙親委派」方式來實現類加載器的層次調用,以儘可能保證JDK的系統API不會被用戶定義的類加載器所破壞,但一些使用場景會打破這個慣例來實現必要的功能。
自定義類加載器
開發可以通過繼承java.lang.ClassLoader
類的方式實現自己的類加載器,以滿足一些特殊的需求而不需要完全了解Java虛擬機的類加載的細節。
可用於:
JEE的類裝載
Java EE (JEE)應用程序服務器典型地用樹狀的一組類裝載器從已部署的WAR或EAR文檔中裝入類。這使得應用程序之間彼此隔離,但共享已部署模塊。servlet container一般被實現為多個類裝載器。[2][8]
JAR地獄
和DLL地獄一樣,一個組件的特定JAR也存在版本差異,不同版本間的JAR文件的Class文件存在差異(包括Class文件的編譯版本、Class的成員結構、Class繼承關係等)的話,也會在運行時觸發各種因為類文件結果衝突而導致的錯誤警告。對於Servlet容器,還存在容器所需的JAR與應用內所需的JAR雙線衝突的問題。
不同於DLL地獄,Java開發者會使用一些項目管理程序(例如Apache Maven)來解決JAR版本之間的衝突,通過配置依賴關係文件,設定不同組件的JAR版本依賴關係,由項目管理程序自動加載相應合適的JAR,來控制JAR間 的版本關係。而對於Servlet容器,也會通過自己實現類加載器打破JDK的「雙親委派」方式來避免JAR加載衝突。
參考文獻
- ^ Mcmanis, Chuck. The basics of Java class loaders. JavaWorld. 1996-10-01 [2008-01-26]. (原始內容存檔於2008-01-20).
- ^ 2.0 2.1 Christudas, Binildas. Internals of Java Class Loading. onjava.com. 2005-01-26 [2009-10-02]. (原始內容存檔於2018-05-10).
- ^ Understanding Extension Class Loading. java.sun.com. 2008-02-14 [2009-12-08]. (原始內容存檔於2009-08-03).
- ^ Sosnoski, Dennis. Classes and class loading. ibm.com. 2003-04-29 [2008-01-26]. (原始內容存檔於2021-01-08).
- ^ 存儲在Jar文件中,如rt.jar, core.jar, server.jar等。
- ^ 存档副本. [2014-05-14]. (原始內容存檔於2020-10-24).
- ^ Roubtsov, Vladimir. Cracking Java byte-code encryption. javaworld.com. 2003-05-09 [2008-01-26]. (原始內容存檔於2008-05-02).
- ^ deBoer, Tim; Karasiuk, Gary. J2EE Class Loading Demystified. ibm.com. 2002-08-21 [2008-01-26]. (原始內容存檔於2008-12-11).
外部連結
- Chuck McManis, "The basics of Java class loaders", 1996
- Brandon E. Taylor, "Java Class Loading: The Basics (頁面存檔備份,存於網際網路檔案館)", 2003
- Jeff Hanson, "Take Control of Class Loading in Java (頁面存檔備份,存於網際網路檔案館)", 2006-06-01
- Andreas Schaefer, "Inside Class Loaders (頁面存檔備份,存於網際網路檔案館)", 2003-11-12
- Sheng Liang and Gilad Bracha, "Dynamic class loading in the Java virtual machine(頁面存檔備份,存於網際網路檔案館)", In Proceedings of the 13th ACM Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA'98), ACM SIGPLAN Notices, vol. 33, no. 10, ACM Press, 1998, pp. 36–44
- Dr. Christoph G. Jung, "Classloaders Revisited Hotdeploy (頁面存檔備份,存於網際網路檔案館)", Java Specialist Newsletter, 2001-06-07
- Don Schwarz, "Managing Component Dependencies Using ClassLoaders (頁面存檔備份,存於網際網路檔案館)", 2005-04-13