中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

類裝載器ClassLoader是什么

發布時間:2021-06-23 10:57:16 來源:億速云 閱讀:111 作者:chen 欄目:大數據

本篇內容介紹了“類裝載器ClassLoader是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

類裝載器ClassLoader

類裝載器工作機制

類裝載器就是尋找類的節碼文件并構造出類在JVM內部表示對象的組件。在Java中,類裝載器把一個類裝入JVM中,要經過以下步驟:

[1.]裝載:查找和導入Class文件; [2.]鏈接:執行校驗、準備和解析步驟,其中解析步驟是可以選擇的: [2.1]校驗:檢查載入Class文件數據的正確性; [2.2]準備:給類的靜態變量分配存儲空間; [2.3]解析:將符號引用轉成直接引用; [3.]初始化:對類的靜態變量、靜態代碼塊執行初始化工作。

類裝載工作由ClassLoader及其子類負責,ClassLoader是一個重要的Java運行時系統組件,它負責在運行時查找和裝入Class字節碼文件。JVM在運行時會產生三個ClassLoader:根裝載器、ExtClassLoader(擴展類裝載器)和AppClassLoader(系統類裝載器)。其中,根裝載器不是ClassLoader的子類,它使用C++編寫,因此我們在Java中看不到它,根裝載器負責裝載JRE的核心類庫,如JRE目標下的rt.jar、charsets.jar等。ExtClassLoader和AppClassLoader都是ClassLoader的子類。其中ExtClassLoader負責裝載JRE擴展目錄ext中的JAR類包;AppClassLoader負責裝載Classpath路徑下的類包。

這三個類裝載器之間存在父子層級關系,即根裝載器是ExtClassLoader的父裝載器,ExtClassLoader是AppClassLoader的父裝載器。默認情況下,使用AppClassLoader裝載應用程序的類,我們可以做一個實驗:

public class ClassLoaderTest {
	public static void main(String[] args) {
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		System.out.println("current loader:"+loader);
		System.out.println("parent loader:"+loader.getParent());
		System.out.println("grandparent loader:"+loader.getParent(). getParent());
	}
}

運行以上代碼,在控制臺上將打出以下信息:

current loader:sun.misc.Launcher$AppClassLoader@131f71a 
parent loader:sun.misc.Launcher$ExtClassLoader@15601ea 
//①根裝載器在Java中訪問不到,所以返回null 
grandparent loader:null

通過以上的輸出信息,我們知道當前的ClassLoader是AppClassLoader,父ClassLoader是ExtClassLoader,祖父ClassLoader是根類裝載器,因為在Java中無法獲得它的句柄,所以僅返回null。

JVM裝載類時使用“全盤負責委托機制”,“全盤負責”是指當一個ClassLoader裝載一個類的時,除非顯式地使用另一個ClassLoader,該類所依賴及引用的類也由這個ClassLoader載入;“委托機制”是指先委托父裝載器尋找目標類,只有在找不到的情況下才從自己的類路徑中查找并裝載目標類。這一點是從安全角度考慮的,試想如果有人編寫了一個惡意的基礎類(如java.lang.String)并裝載到JVM中將會引起多么可怕的后果。但是由于有了“全盤負責委托機制”,java.lang.String永遠是由根裝載器來裝載的,這樣就避免了上述事件的發生。

ClassLoader重要方法

在Java中,ClassLoader是一個抽象類,位于java.lang包中。下面對該類的一些重要接口方法進行介紹:

  • Class loadClass(String name) name參數指定類裝載器需要裝載類的名字,必須使用全限定類名,如com.baobaotao. beans.Car。該方法有一個重載方法loadClass(String name ,boolean resolve),resolve參數告訴類裝載器是否需要解析該類。在初始化類之前,應考慮進行類解析的工作,但并不是所有的類都需要解析,如果JVM只需要知道該類是否存在或找出該類的超類,那么就不需要進行解析。

  • Class defineClass(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。

除JVM默認的三個ClassLoader以外,可以編寫自己的第三方類裝載器,以實現一些特殊的需求。類文件被裝載并解析后,在JVM內將擁有一個對應的java.lang.Class類描述對象,該類的實例都擁有指向這個類描述對象的引用,而類描述對象又擁有指向關聯ClassLoader的引用,如圖所示。

每一個類在JVM中都擁有一個對應的java.lang.Class對象,它提供了類結構信息的描述。數組、枚舉、注解以及基本Java類型(如int、double等),甚至void都擁有對應的Class對象。Class沒有public的構造方法。Class對象是在裝載類時由JVM通過調用類裝載器中的defineClass()方法自動構造的。

類的初始化

類什么時候才被初始化

  1. 創建類的實例,也就是new一個對象

  2. 訪問某個類或接口的靜態變量,或者對該靜態變量賦值

  3. 調用類的靜態方法

  4. 反射(Class.forName("com.lyj.load"))

  5. 初始化一個類的子類(會首先初始化子類的父類)

  6. JVM啟動時標明的啟動類,即文件名和類名相同的那個類

只有這6中情況才會導致類的類的初始化。

類的初始化步驟:

  1. 如果這個類還沒有被加載和鏈接,那先進行加載和鏈接

  2. 假如這個類存在直接父類,并且這個類還沒有被初始化(注意:在一個類加載器中,類只能初始化一次),那就初始化直接的父類(不適用于接口)

  3. 加入類中存在初始化語句(如static變量和static塊),那就依次執行這些初始化語句。

“類裝載器ClassLoader是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泸水县| 孝昌县| 肥乡县| 高要市| 澳门| 黎平县| 阿克陶县| 永清县| 静海县| 罗源县| 阜康市| 鄄城县| 自治县| 诏安县| 宝兴县| 海门市| 丰都县| 米泉市| 阳高县| 慈溪市| 嘉善县| 铁岭市| 孟州市| 西畴县| 拉孜县| 汨罗市| 清丰县| 赣榆县| 乌鲁木齐县| 同仁县| 禄劝| 永城市| 友谊县| 乌恰县| 双牌县| 泽普县| 汉寿县| 万盛区| 邵武市| 丰县| 明溪县|