1. 程式人生 > >1.java類載入器?

1.java類載入器?

Java類載入器ClassLoader總結

JAVA類裝載方式,有兩種:

1.隱式裝載, 程式在執行過程中當碰到通過new 等方式生成物件時,隱式呼叫類裝載器載入對應的類到jvm中。

2.顯式裝載, 通過class.forname()等方法,顯式載入需要的類

類載入的動態性體現:

一個應用程式總是由n多個類組成,Java程式啟動時,並不是一次把所有的類全部載入後再執行,它總是先把保證程式執行的基礎類一次性載入到jvm中,其它類等到jvm用到的時候再載入,這樣的好處是節省了記憶體的開銷,因為java最早就是為嵌入式系統而設計的,記憶體寶貴,這是一種可以理解的機制,而用到時再載入這也是java動態性的一種體現

java類裝載器

JDK 預設提供瞭如下幾種ClassLoader

  1. Bootstrp loader
    Bootstrp載入器是用C++語言寫的,它是在Java虛擬機器啟動後初始化的,它主要負責載入%JAVA_HOME%/jre/lib,-Xbootclasspath引數指定的路徑以及%JAVA_HOME%/jre/classes中的類。

  1. ExtClassLoader  
    Bootstrp loader載入ExtClassLoader,並且將ExtClassLoader的父載入器設定為Bootstrp loader.ExtClassLoader是用Java寫的,具體來說就是 sun.misc.Launcher$ExtClassLoader,ExtClassLoader主要載入%JAVA_HOME%/jre/lib/ext

    ,此路徑下的所有classes目錄以及java.ext.dirs系統變數指定的路徑中類庫。

  2. AppClassLoader 
    Bootstrp loader載入完ExtClassLoader後,就會載入AppClassLoader,並且將AppClassLoader的父載入器指定為 ExtClassLoader。AppClassLoader也是用Java寫成的,它的實現類是 sun.misc.Launcher$AppClassLoader,另外我們知道ClassLoader中有個getSystemClassLoader方法,此方法返回的正是AppclassLoader.AppClassLoader主要負責載入classpath所指定的位置的類或者是jar文件,它也是Java程式預設的類載入器。

綜上所述,它們之間的關係可以通過下圖形象的描述:

 

 

為什麼要有三個類載入器,一方面是分工,各自負責各自的區塊,另一方面為了實現委託模型。


 類載入器之間是如何協調工作的

前面說了,java中有三個類載入器,問題就來了,碰到一個類需要載入時,它們之間是如何協調工作的,即java是如何區分一個類該由哪個類載入器來完成呢。 在這裡java採用了委託模型機制,這個機制簡單來講,就是“類裝載器有載入類的需求時,會先請示其Parent使用其搜尋路徑幫忙載入,如果Parent 找不到,那麼才由自己依照自己的搜尋路徑搜尋類

下面舉一個例子來說明,為了更好的理解,先弄清楚幾行程式碼:

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Public class Test{

 

    Public static void main(String[] arg){

 

      ClassLoader c  = Test.class.getClassLoader();  //獲取Test類的類載入器

 

        System.out.println(c);

 

      ClassLoader c1 = c.getParent();  //獲取c這個類載入器的父類載入器

 

        System.out.println(c1);

 

      ClassLoader c2 = c1.getParent();//獲取c1這個類載入器的父類載入器

 

        System.out.println(c2);

 

  }

 

}

執行結果:

Java

 

1

2

3

4

5

……AppClassLoader……

 

……ExtClassLoader……

 

Null

可以看出Test是由AppClassLoader載入器載入的,AppClassLoaderParent 載入器是 ExtClassLoader,但是ExtClassLoaderParent為 null 是怎麼回事呵,朋友們留意的話,前面有提到Bootstrap Loader是用C++語言寫的,依java的觀點來看,邏輯上並不存在Bootstrap Loader的類實體,所以在java程式程式碼裡試圖打印出其內容時,我們就會看到輸出為null