1. 程式人生 > >JVM載入class檔案的原理機制是什麼?類載入器的工作原理

JVM載入class檔案的原理機制是什麼?類載入器的工作原理

Java語言是一種具有動態性的解釋型語言,類(class)只有被載入到JVM中後才能執行。當執行指定程式時,JVM會將編譯生成的.class檔案按照需求和一定的規則載入到記憶體中,並組織成為一個完整的Java應用程式。這個載入過程是由類載入器來完成的,具體來說,就是由ClassLoader和它的子類來實現的。類載入器本身也是一個類,其實質是把類檔案從硬碟讀取到記憶體中。

類的載入方式分為隱式載入與顯式載入兩種。隱式載入指的是程式在使用new等方法建立物件時,會隱式地呼叫類的載入器把對應的類載入到JVM中。顯式載入指的是通過直接呼叫class.forName()方法來把所需要的類載入到JVM中。

任何一個工程專案都是由許多個類組成的,當程式啟動時,只把需要載入的類載入到JVM中,其他類只有被使用到的時候才會被載入,採用這種方法,一方面可以加快載入速度,另外一方面可以節約程式執行過程中對記憶體的開銷。此外,在Java語言中,每個類或介面都對應一個.class檔案,這些檔案可以被看成一個個可以被動態載入的單元,因此當只有部分類被修改時,只需要重新編譯變化的類即可,而不需要重新編譯所有檔案,因此加快了編譯速度。

在Java語言中,類的載入是動態的,它並不會一次性將所有的類全部載入後再執行,而是保證程式執行的基礎類(例如基類)完全載入到JVM中,至於其他類,則在需要時才載入。在Java語言中,可以把類分為3類:系統類、擴充套件類和自定義類。Java針對這3種不同的類提供了3中型別的載入器,這3種載入器的關係如下:


以上這三個類是如何協調工作來完成類的載入呢?

其實,它們是通過委託的方式實現的。具體而言,就是當有類需要被載入時,類載入器會請求父類來完成這個載入工作,父類會使用其自己的搜尋路徑來搜尋需要被載入的類,如果搜尋不到,才會由子類按照其搜尋路徑來搜尋待載入的類。下例可以充分說明類載入器的工作原理:

package com.js;
/**
 * 說明類載入器的工作原理
 * @author jiangshuai
 *
 */
public class TestLoader {
	public static void main(String[] args){
		//呼叫Class載入器
		ClassLoader clApp = TestLoader.class.getClassLoader();
		System.out.println(clApp);
		//呼叫上一層Class載入器
		ClassLoader clExt = clApp.getParent();
		System.out.println(clExt);
		//呼叫根部Class載入器
		ClassLoader clBoot = clExt.getParent();
		System.out.println(clBoot);
	}
}
執行結果:

[email protected]
[email protected]
null

從上例可以看出,TestLoader類是由AppClassLoader來載入的。另外需要說明的一點是,由於Bootstrap Loader是用C++語言來實現的,因此,在Java語言中是看不到它的,所以此時程式會輸出null。

類載入的主要步驟分為以下3步:

1、裝載。根據查詢路徑找到相對應的class檔案,然後匯入。

2、連結。連結又可以分為3個小的步驟,具體如下。

1)檢查。檢查待載入的class檔案的正確性。

2)準備。給類中的靜態變數分配儲存空間。

3)解析。將符號引用轉換成直接引用(這一步是可選的)。

3、初始化。對靜態變數和靜態程式碼塊執行初始化工作。