Java虛擬機類裝載的原理及實現
一、引言
Java虛擬機(JVM)的類裝載就是指將包含在類文件中的字節碼裝載到JVM中, 并使其成為JVM一部分的過程。JVM的類動態裝載技術能夠在運行時刻動態地加載或者替換系統的某些功能模塊, 而不影響系統其他功能模塊的正常運行。本文將分析JVM中的類裝載系統,探討JVM中類裝載的原理、實現以及應用。
二、Java虛擬機的類裝載實現與應用
2.1 裝載過程簡介
所謂裝載就是尋找一個類或是一個接口的二進制形式并用該二進制形式來構造代表這個類或是這個接口的class對象的過程,其中類或接口的名稱是給定了的。當然名稱也可以通過計算得到,但是更常見的是通過搜索源代碼經過編譯器編譯后所得到的二進制形式來構造。
在Java中,類裝載器把一個類裝入Java虛擬機中,要經過三個步驟來完成:裝載、鏈接和初始化,其中鏈接又可以分成校驗、準備和解析三步,除了解析外,其它步驟是嚴格按照順序完成的,各個步驟的主要工作如下:
裝載:查找和導入類或接口的二進制數據;
鏈接:執行下面的校驗、準備和解析步驟,其中解析步驟是可以選擇的;
校驗:檢查導入類或接口的二進制數據的正確性;
準備:給類的靜態變量分配并初始化存儲空間;
解析:將符號引用轉成直接引用;
初始化:激活類的靜態變量的初始化Java代碼和靜態Java代碼塊。
至于在類裝載和虛擬機啟動的過程中的具體細節和可能會拋出的錯誤,請參看《Java虛擬機規范》以及《深入Java虛擬機》。 由于本文的討論重點不在此就不再多敘述。
2.2 裝載的實現
JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader 是一個重要的Java運行時系統組件。它負責在運行時查找和裝入類文件的類。
在Java中,ClassLoader是一個抽象類,它在包java.lang中,可以這樣說,只要了解了在ClassLoader中的一些重要的方法,再結合上面所介紹的JVM中類裝載的具體的過程,對動態裝載類這項技術就有了一個比較大概的掌握,這些重要的方法包括以下幾個:
①loadCass方法 loadClass(String name ,boolean resolve)其中name參數指定了JVM需要的類的名稱,該名稱以包表示法表示,如Java.lang.Object;resolve參數告訴方法是否需要解析類,在初始化類之前,應考慮類解析,并不是所有的類都需要解析,如果JVM只需要知道該類是否存在或找出該類的超類,那么就不需要解析。這個方法是ClassLoader 的入口點。
②defineClass方法 這個方法接受類文件的字節數組并把它轉換成Class對象。字節數組可以是從本地文件系統或網絡裝入的數據。它把字節碼分析成運行時數據結構、校驗有效性等等。
③findSystemClass方法 findSystemClass方法從本地文件系統裝入文件。它在本地文件系統中尋找類文件,如果存在,就使用defineClass將字節數組轉換成Class對象,以將該文件轉換成類。當運行Java應用程序時,這是JVM 正常裝入類的缺省機制。
④resolveClass方法 resolveClass(Class c)方法解析裝入的類,如果該類已經被解析過那么將不做處理。當調用loadClass方法時,通過它的resolve 參數決定是否要進行解析。
⑤findLoadedClass方法 當調用loadClass方法裝入類時,調用findLoadedClass 方法來查看ClassLoader是否已裝入這個類,如果已裝入,那么返回Class對象,否則返回NULL。如果強行裝載已存在的類,將會拋出鏈接錯誤。
Java虛擬機(JVM)的類裝載就是指將包含在類文件中的字節碼裝載到JVM中, 并使其成為JVM一部分的過程。JVM的類動態裝載技術能夠在運行時刻動態地加載或者替換系統的某些功能模塊, 而不影響系統其他功能模塊的正常運行。本文將分析JVM中的類裝載系統,探討JVM中類裝載的原理、實現以及應用。
二、Java虛擬機的類裝載實現與應用
2.1 裝載過程簡介
所謂裝載就是尋找一個類或是一個接口的二進制形式并用該二進制形式來構造代表這個類或是這個接口的class對象的過程,其中類或接口的名稱是給定了的。當然名稱也可以通過計算得到,但是更常見的是通過搜索源代碼經過編譯器編譯后所得到的二進制形式來構造。
在Java中,類裝載器把一個類裝入Java虛擬機中,要經過三個步驟來完成:裝載、鏈接和初始化,其中鏈接又可以分成校驗、準備和解析三步,除了解析外,其它步驟是嚴格按照順序完成的,各個步驟的主要工作如下:
裝載:查找和導入類或接口的二進制數據;
鏈接:執行下面的校驗、準備和解析步驟,其中解析步驟是可以選擇的;
校驗:檢查導入類或接口的二進制數據的正確性;
準備:給類的靜態變量分配并初始化存儲空間;
解析:將符號引用轉成直接引用;
初始化:激活類的靜態變量的初始化Java代碼和靜態Java代碼塊。
至于在類裝載和虛擬機啟動的過程中的具體細節和可能會拋出的錯誤,請參看《Java虛擬機規范》以及《深入Java虛擬機》。 由于本文的討論重點不在此就不再多敘述。
2.2 裝載的實現
JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader 是一個重要的Java運行時系統組件。它負責在運行時查找和裝入類文件的類。
在Java中,ClassLoader是一個抽象類,它在包java.lang中,可以這樣說,只要了解了在ClassLoader中的一些重要的方法,再結合上面所介紹的JVM中類裝載的具體的過程,對動態裝載類這項技術就有了一個比較大概的掌握,這些重要的方法包括以下幾個:
①loadCass方法 loadClass(String name ,boolean resolve)其中name參數指定了JVM需要的類的名稱,該名稱以包表示法表示,如Java.lang.Object;resolve參數告訴方法是否需要解析類,在初始化類之前,應考慮類解析,并不是所有的類都需要解析,如果JVM只需要知道該類是否存在或找出該類的超類,那么就不需要解析。這個方法是ClassLoader 的入口點。
②defineClass方法 這個方法接受類文件的字節數組并把它轉換成Class對象。字節數組可以是從本地文件系統或網絡裝入的數據。它把字節碼分析成運行時數據結構、校驗有效性等等。
③findSystemClass方法 findSystemClass方法從本地文件系統裝入文件。它在本地文件系統中尋找類文件,如果存在,就使用defineClass將字節數組轉換成Class對象,以將該文件轉換成類。當運行Java應用程序時,這是JVM 正常裝入類的缺省機制。
④resolveClass方法 resolveClass(Class c)方法解析裝入的類,如果該類已經被解析過那么將不做處理。當調用loadClass方法時,通過它的resolve 參數決定是否要進行解析。
⑤findLoadedClass方法 當調用loadClass方法裝入類時,調用findLoadedClass 方法來查看ClassLoader是否已裝入這個類,如果已裝入,那么返回Class對象,否則返回NULL。如果強行裝載已存在的類,將會拋出鏈接錯誤。