對于java類加載器的認識(1)
作者:早餐2塊2
java是具有動態性,什么是動態性?有個最直觀的例子:windows系統的即插即用,支持即插即用的設備可以在系統不重新啟動的情況下既可以熱把插使用。而java的動態性表現在:我們的程序可以不用全盤的重新編譯就能對程序某部分進行更新,C#也和java一樣具有動態性,而且它的這種動態性表現更為直觀:直接生成windows的動態連接庫文件——dll文件。而java生成的是class文件,class是怎么實現動態性的了,這個時候就全靠我們今天的主角:java的類加載器。
我們都知道所有的java類都是繼承了object這個類,在object這個類中有一個方法:getclass(),這個方法返回的是一個Class類對象,具體見:認識java的Class類
一旦一個類被載入JVM中,同一個類就不會被再次載入了(切記,同一個類)。這里存在一個問題就是什么是“同一個類”?正如一個對象有一個具體的狀態,即標識,一個對象始終和其代碼(類)相關聯(見文認識java的Class類)。同理,載入JVM的類也應該有一個具體的標識,我們知道:在JAVA中,一個類用其完全匹配類名(fully qualified class name)作為標識,這里指的完全匹配類名是包名和類名。不過在JVM中一個類是用其全名再附加上一個加載類ClassLoader的實例作為唯一標識。因此,如果一個名為Pg的包中,有一個名為Cl的類,被類加載器KlassLoader的一個實例對象kl1加載,生成Cl的對象,即C1.class(這里指類,而非對象)在JVM中表示為(Cl, Pg, kl1)。這意味著兩個類加載器的實例(Cl, Pg, kl1) 和 (Cl, Pg, kl2)是不同的,被它們所加載的類也因此完全不同,互不兼容的。
在java中每個類都是由某個類加載器的實體來載入的,因此在Class類的實體中,都會有字段記錄載入它的類加載器的實體(當為null時,其實是指Bootstrap ClassLoader)。 在java類加載器中除了引導類加載器(既Bootstrap ClassLoader),所有的類加載器都有一個父類加載器(因為他們本身自己就是java類)。而類的加載機制是遵循一種委托模式:當類加載器有加載類的需求時,會先請求其Parent加載(依次遞歸),如果在其父加載器樹中都沒有成功加載該類,則由當前類加載器加載。
java的類加載器分為以下幾種:
1,Bootstrap ClassLoader,用C++實現,一切的開始,是所有類加載器的最終父加載器。負責將一些關鍵的Java類,如java.lang.Object和其他一些運行時代碼先加載進內存中。
2,ExtClassLoader,用java實現,是Launcher.java的內部類,編譯后的名字為:Launcher$ExtClassLoader.class 。此類由Bootstrap ClassLoader加載,但由于Bootstrap ClassLoader已經脫離了java體系(c++),所以Launcher$ExtClassLoader.class的Parent(父加載器)被設置為null;它用于裝載Java運行環境擴展包(jre/lib/ext)中的類,而且一旦建立其加載的路徑將不再改變。
3,AppClassLoader,用java實現,也是是Launcher.java的內部類,編譯后的名字為:Launcher$AppClassLoader.class 。AppClassLoader是當Bootstrap ClassLoader加載完ExtClassLoader后,再被Bootstrap ClassLoader加載。所以ExtClassLoader和AppClassLoader都是被Bootstrap ClassLoader加載,但AppClassLoader的Parent被設置為ExtClassLoader。可見Parent和由哪個類加載器來加載不一定是對應的。
個類裝載器是我們經常使用的,可以調用ClassLoader.getSystemClassLoader() 來獲得,如果程序中沒有使用類裝載器相關操作設定或者自定義新的類裝載器,那么我們編寫的所有java類都會由它來裝載。而它的查找區域就是我們常常說到的Classpath,一旦建立其加載路徑也不再改變。
4,ClassLoader:一般我們自定義的ClassLoader從ClassLoader類繼承而來。比如:URLClassloader是ClassLoader的一個子類,而URLClassloader也是ExtClassLoader和AppClassLoader的父類(注意不是父加載器)。
posted on 2005-11-24 15:53 早餐2塊2 閱讀(6902) 評論(1) 編輯 收藏 所屬分類: java基礎