1. 程式人生 > >Java類載入器詳解&雙親委派模式

Java類載入器詳解&雙親委派模式

一、Java虛擬機種的類載入器

1、類載入器種類

         Java虛擬機器中可以安裝多個類載入器,系統預設三個主要的類載入器,每個類負責載入特定位置的類:

         BootStrap類載入器也是Java類,因為Java類的類載入器本身也是要被類載入器載入的,顯然必須有第一個類載入器不是Java類,這個正是BootStrap,使用C/C++程式碼寫的,已經封裝到JVM核心中了,而ExtClassLoaderAppClassLoaderJava類。

         ExtClassLoader

         AppClassLoader

2、類載入器的屬性結構圖及原理——雙親委派模型


類載入器的委託機制-載入原理:

      1每個類載入器載入類時,又先委託給其上級類載入器當所有祖宗類載入器沒有載入到類,回到發起者類載入器,還載入不了,則會丟擲ClassNotFoundException,不是再去找發起者類載入器的兒子,因為沒有getChild()方法。例如:如上圖所示:MyClassLoader->AppClassLoader->Ext-ClassLoader->BootStrap.自定定義的MyClassLoader1首先會先委託給AppClassLoader,AppClassLoader會委託給ExtClassLoader,ExtClassLoader

會委託給BootStrap,這時候BootStrap就去載入,如果載入成功,就結束了。如果載入失敗,就交給ExtClassLoader去載入,如果ExtClassLoader載入成功了,就結束了,如果載入失敗就交給AppClassLoader載入,如果載入成功,就結束了,如果載入失敗,就交給自定義的MyClassLoader1類載入器載入,如果載入失敗,就報ClassNotFoundException異常,結束。

這裡需要注意的是上述三個JDK提供的類載入器雖然是父子類載入器關係,但是沒有使用繼承,而是使用了組合關係。

          ——上述過程即雙親委派模型:優點是java的類載入器一起具備了一種帶優先順序的層次關係,越是基礎的類,越是被上層的類載入器進行載入,保證了

java程式的穩定執行

2如果類A中引用了類B,Java虛擬機器將使用載入類A的類載入器來載入類B

3可以直接呼叫ClassLoader.loadClass(StringclassName)方法來指定某個類載入器去載入某個類

4)首先當前執行緒的類載入器去載入執行緒中的第一個類(當前執行緒的類載入器:Thread類中有一個get/setContextClassLoader(ClassLoadercl);方法,可以獲取/指定本執行緒中的類載入器)

3、例子:


輸出結果:


note

1因為System類,ListMap等這樣的系統提供jar類都在jre/lib/rt.jar中,所以由BootStrap類載入器載入,因為BootStrap是祖先類,不是Java編寫的,所以打印出classnull

2)ClassLoaderTest.java打包成.jar檔案,後將.jar檔案拷貝到Java的安裝目錄中的Java/jre7/lib/ext/目錄下,結果ClassLoaderTest的類載入器變成了ExtClassLoader,如下:


二、自定義類載入器

1、自定義的類載入器預設的都是將掛載到系統類載入器的最低端AppClassLoader

loadClass(name,false)方法的原始碼:

執行流程是:每個類載入器:loadClass→findClass→defineClass.

findClass這個方法就是根據name來查詢到class檔案,在loadClass方法中用到,所以我們只能重寫這個方法了,只要在這個方法中找到class檔案,再將它用defineClass方法返回一個Class物件即可。defineClass這個方法很簡單就是將class檔案的位元組陣列程式設計一個class物件,這個方法肯定不能重寫,內部實現是在C/C++程式碼中實現的

2、自定義類載入器實現

1)首先,定義需要載入的一個類:ClassLoaderAttachment.java,編譯成ClassLoaderAttachment.class檔案,放到工程目錄下。


2)定義自定義類載入器


3)測試類:


輸出結果:


note

因為loadClass方法在使用系統類載入器AppClassLoader的時候需要傳遞全稱(包括包名),我們傳遞ClassLoaderAttachment的話,AppClassLoader也是沒有找到這個ClassLoaderAttachment,所以還是MyClassLoader處理了。

        如果改成:


結果:


例子中class檔案可以加密,具體可參考文章:

http://www.wjdiankong.cn/java高新技術第一篇:類載入器詳解/