日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JVM——三个ClassLoader详解

發布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM——三个ClassLoader详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  類裝載工作由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路徑下的類包。

  • 啟動類加載器(Bootstrap ClassLoader):這個類加載器負責將存放在<JAVA_HOME>\lib目錄中的。啟動類加載器無法被Java程序直接引用,用戶在編寫自定義類加載器時,如果需要把加載請求委派給引導類加載器,那直接使用null代替即可。
  • 擴展類加載器(Extension ClassLoader):這個加載器由sun.misc.Launcher$ExtClassLoader實現,它負責加載<JAVA_HOME>\lib\ext目錄中的,或者被java.ext.dirs系統變量所指定的路徑中的所有類庫,開發者可以直接使用擴展類加載器。
  • 應用程序類加載器(Application ClassLoader):這個類加載器由sun.misc.Launcher$AppClassLoader實現。由于這個類加載器是ClassLoader中的getSystemClassLoader()方法的返回值,所以一般也稱它為系統類加載器。它負責加載用戶類路徑(ClassPath)上所指定的類庫,開發者可以直接使用這個類加載器,如果應用程序中沒有自定義自己的類加載器,一般情況下這個就是程序中默認的類加載器。

  我們的應用程序都是由這3種類加載器互相配合進行加載的,如果有必要,還可以加入自己定義的類加載器。這些類加載器之間的關系一般為:

  上圖展示的類加載器之間的這種層次關系,稱為類加載器的雙親委派模型。雙親委派模型要求除了頂層的啟動類加載器外,其余的類加載器都應當有自己的父類加載器。這里類加載器之間的父子關系一般不會以繼承的關系來實現,而是都使用組合關系來復用父加載器的代碼。

  類加載器的雙親委派模型詳解博客鏈接

  這三個類裝載器之間存在父子層級關系,即根裝載器是ExtClassLoader的父裝載器,ExtClassLoader是父類裝載器。默認情況下,使用AppClassLoader裝載應用程序的類,用以下代碼證明:

1 /** 2 * @author zhengbinMac 3 */ 4 public class ClassLoaderTest { 5 6 public static void main(String[] args) { 7 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 8 System.out.println("current loader:" + loader); 9 System.out.println("parent loader:" + loader.getParent()); 10 System.out.println("grandparent loader:" + loader.getParent().getParent()); 11 } 12 /* 13 * output: 14 * current loader:sun.misc.Launcher$AppClassLoader@1b6d3586 15 * parent loader:sun.misc.Launcher$ExtClassLoader@1540e19d 16 * grandparent loader:null // 因為根類裝載器在Java中訪問不到,所有返回null 17 */ 18 }

  Thread.currentThread():返回對當前正在執行的線程對象的引用。

  getContextClassLoader():返回該線程的上下文 ClassLoader。

  通過以上的輸出信息,可以明白,ClassLoader是AppClassLoader,父ClassLoader是ExtClassLoader,祖父ClassLoader是根類裝載器,因為在Java中無法獲得它的句柄,所以直接返回null。

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

ClassLoader重要方法


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

  • Class loadClass(String name)

  name參數指定類裝載器需要裝載類的名字,必須使用全限定類名,如com.zhengbin.entity.Student。該方法有一個重載方法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默認使用的裝載機制。

  • ClassLoader getParent()

  獲取類裝載器的父裝載器,除根裝載器外,所有的類裝載器都有且僅有一個父裝載器,ExtClassLoader的父裝載器是根裝載器,因為根裝載器非Java編寫,所以無法獲得,將返回null。

轉載于:https://www.cnblogs.com/zhengbin/p/5631987.html

總結

以上是生活随笔為你收集整理的JVM——三个ClassLoader详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。