類裝載器的工做機制
類裝載器就是尋找類的字節碼文件並構造出類在JVM內部表示對象的組件。在Java中,類裝載器把一個類裝入JVM中,須要通過如下步驟:java
- 裝載:查找和導入Class文件。
- 連接:執行校驗、準備和解析步驟,其中解析步驟是能夠選擇的。
- 校驗:檢查載入Class文件數據的正確性。
- 準備:給類的靜態變量分配存儲空間。
- 解析:將符號引用轉換成直接引用。
- 初始化:對類的靜態變量、靜態代碼塊執行初始化工做。
類裝載工做由ClassLoader及其子類負責。ClassLoader是一個重要的Java運行時系統組件,它負責在運行時查找和裝入Class字節碼文件,JVM在運行會產生3個ClassLoader:根裝載器、ExtClassLoader(擴展類裝載器)和AppClassLoader(應用類裝載器)。其中,根裝載不是ClassLoader的子類,它使用C++語言編寫,於是在Java中看不到它,根裝載器負責裝載JRE的核心類庫,如JRE目標下的rt.jar、charsets.jar等。ExtClassLoader和AppClassLoader都是ClassLoader的子類,其中ExtClassLoader負責裝載JRE擴展目錄ext中的JAR類包;AppClassLoader負責裝載Classpath路徑下的類包。
這3個類裝載器之間存在父子層級關係,即根裝載器是ExtClassLoader的父裝載器,ExtClassLoader是AppClassLoaderde父裝載器。在默認狀況下,使用AppClassLoader裝載應用程序的類。數組
JVM裝在類時使用"全盤負責委託機制","全盤負責"是指當一個ClassLoader裝載一個類時,除非顯式地使用另外一個ClassLoader,該類所依賴及引用也由這個ClassLoader載入;"委託機制"是指先委託父裝載器尋找目標類,只有在找不到的狀況下才從本身的類路徑下查找並裝載目標類。這一點是從安全角度考慮的。安全
ClassLoader的重要方法
在Java中,ClassLoader是一個抽象類,位於java.lang包中。下面對該類的一些重要接口方法進行介紹。網絡
- Class loadClass(String name): name參數指定類裝載器須要裝載類的名字,必須使用全限定類名。該方面有一個重載方法loadClass(String name,boolean resolve),resolve參數告訴裝載器是否須要解析該類,在初始化類以前,應考慮進行類解析的工做,但並非全部的類都須要解析該類。若是JVM只須要知道該類是否存在或找出該類的超類,那麼就不須要進行解析。
- Class definClass(String name,byte[] b,int off,int len): 將類文件的字節數組轉換成JVM內部的java.lang.Class對象,字節數組能夠從本地文件系統、遠程網絡獲取。參數name爲字節數組對應的全限定類名。
- Class findSystemClass(String name):從本地文件系統載入Class文件。若是本地文件系統不存在該Class文件,則將拋出ClassNotFoundException異常,該方法是JVM默認使用的裝載機制。
- CLass findLoadedClass(String name): 調用該方法來查看ClassLoader是否已經裝入某個類。若是已裝入,那麼返回java.lang.Class對象;不然返回null,若是強行裝載已存在的類,那麼將會拋出連接錯誤。
- ClassLoader getParent():獲取類裝載器的父裝載器。除根裝載器外,全部的類裝載器有且僅有一個父裝載器。ExtClassLoader的父裝載器是根裝載器,由於根裝載器非Java語言編寫,因此沒法得到,將返回null。