91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

Java中的ClassLoader核心知識點有哪些

發布時間:2021-10-25 13:55:03 來源:億速云 閱讀:200 作者:iii 欄目:編程語言

這篇文章主要介紹“Java中的ClassLoader核心知識點有哪些”,在日常操作中,相信很多人在Java中的ClassLoader核心知識點有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java中的ClassLoader核心知識點有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

JDK 和 JRE 的作用

  • JDK 提供了 java 的編程環境,它包含編譯調試的環境功能,包含 JRE(JDK 目錄中的 JRE 為專用 JRE,而安裝后與 JDK 同目錄的  JRE 為公用 JRE)。開發時一般運行的是 JDK 專用JRE,而運行外部程序時一般運行的是公用 JRE,實現了分工不同的 jre  負責各自范圍的內容。

  • JRE 提供了 JAVA 程序運行的必要環境平臺

JAVAHOME、PATH、CLASSPATH

  • JAVAHOME: JDK安裝的位置路徑,如:D:\Program Files\Java\jdk1.8.0_241

  • PATH: 配置后運行 bin 中的命令不需要補全全路徑,如可以在任意的位置運行 java 和 javac 命令,  %JAVA_HOME%\bin;

  • CLASSPATH:指向jar包路徑 %JAVA_HOME%\lib;

類加載器的種類

在JVM中有三類ClassLoader構成:

  • Bootstrap ClassLoader 啟動類(或根類)加載器

  • Extention ClassLoader 擴展的類加載器

  • Appclass Loader 應用類加載器

Java中的ClassLoader核心知識點有哪些

(1) Bootstrap ClassLoader

Bootstrap ClassLoader 最頂層的類加載器,主要加載核心類庫 %JRE_HOME%\lib 下的  rt.jar、resources.jar、charsets.jar 和 class文件等。

//執行 System.out.println(System.getProperty("sun.boot.class.path")); //輸出結果 D:\Program Files\Java\jdk1.8.0_241\jre\lib\resources.jar; D:\Program Files\Java\jdk1.8.0_241\jre\lib\rt.jar; D:\Program Files\Java\jdk1.8.0_241\jre\lib\sunrsasign.jar; D:\Program Files\Java\jdk1.8.0_241\jre\lib\jsse.jar; D:\Program Files\Java\jdk1.8.0_241\jre\lib\jce.jar; D:\Program Files\Java\jdk1.8.0_241\jre\lib\charsets.jar; D:\Program Files\Java\jdk1.8.0_241\jre\lib\jfr.jar; D:\Program Files\Java\jdk1.8.0_241\jre\classes

(2) Extention ClassLoader

Extention ClassLoader 擴展的類加載器,主要加載目錄 %JRE_HOME%\lib\ext 目錄下的jar包和class文件。

//執行 System.out.println(System.getProperty("java.ext.dirs")); //輸出 D:\Program Files\Java\jdk1.8.0_241\jre\lib\ext;C:\Windows\Sun\Java\lib\ext

(3) Appclass Loader

Appclass Loader也稱為SystemAppClass 加載當前應用的classpath的所有類。

類加載器的執行順序

除啟動類加載器(Bootstrap  ClassLoader)外,擴展類加載器和應用類加載器都是通過類sun.misc.Launcher進行初始化,而Launcher類則由啟動類加載器進行加載。Launcher相關代碼如下:

public Launcher() {     Launcher.ExtClassLoader var1;     try {         //初始化擴展類加載器,構造函數沒有入參,無法獲取啟動類加載器         var1 = Launcher.ExtClassLoader.getExtClassLoader();     } catch (IOException var10) {         throw new InternalError("Could not create extension class loader", var10);     }      try {         //初始化應用類加載器,入參為擴展類加載器         this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);     } catch (IOException var9) {         throw new InternalError("Could not create application class loader", var9);     }      // 設置上下文類加載器     Thread.currentThread().setContextClassLoader(this.loader);         //... }

加載順序:Bootstrap CLassloder > Extention ClassLoader > AppClassLoader

父加載器概念

AppClassLoader 和 ExtClassLoader 都繼承了  URLClassLoader。每個類加載器都有一個父加載器(注意:父類和父加載器是兩個不同的概念),可通過 getParent() 獲取父類加載器。

System.out.println("ClassLoader is:"+cl.toString()); System.out.println("ClassLoader\'s parent is:"+cl.getParent().toString());System.out.println("ClassLoader\'s grand father is:"+cl.getParent().getParent().toString());
  • AppClassLoader 的父加載器是ExtClassLoader

  • ExtClassLoader的父加載器是Bootstrap ClassLoader(上面代碼輸出 ExtClassLoader 為null 是因為  Bootstrap ClassLoader 本身不是一個Java 類所致)

  • Bootstrap  ClassLoader是由C/C++編寫的,它本身是虛擬機的一部分,所以它并不是一個JAVA類,也就是無法在java代碼中獲取它的引用,JVM啟動時通過Bootstrap類加載器加載rt.jar等核心jar包中的class文件,之前的int.class,String.class都是由它加載。然后呢,我們前面已經分析了,JVM初始化sun.misc.Launcher并創建Extension  ClassLoader和AppClassLoader實例。并將ExtClassLoader設置為AppClassLoader的父加載器。Bootstrap沒有父加載器,但是它卻可以作用一個ClassLoader的父加載器。

雙親委派

雙親委派模型:當一個類加載器接收到類加載請求時,會先請求其父類加載器加載,依次遞歸,當父類加載器無法找到該類時(根據類的全限定名稱),子類加載器才會嘗試去加載。

Java中的ClassLoader核心知識點有哪些

Java中的ClassLoader核心知識點有哪些

時序圖

為什么使用雙親委派模型?

雙親委派模型是為了保證Java核心庫的類型安全。所有Java應用都至少需要引用java.lang.Object類,在運行時這個類需要被加載到Java虛擬機中。如果該加載過程由自定義類加載器來完成,可能就會存在多個版本的java.lang.Object類,而且這些類之間是不兼容的。

通過雙親委派模型,對于Java核心庫的類的加載工作由啟動類加載器來統一完成,保證了Java應用所使用的都是同一個版本的Java核心庫的類,是互相兼容的。

自定義類加載器

不管是Bootstrap  ClassLoader還是ExtClassLoader等,這些類加載器都只是加載指定的目錄下的jar包或者資源。如果我們需要動態加載比如從指定目錄中加載一個class文件,這時候通過自定義類加載器可以實現。

自定義類加載器只需要繼承java.lang.ClassLoader類,然后重寫findClass(String  name)方法即可,在方法中指明如何獲取類的字節碼流。如果要破壞雙親委派規范的話,還需重寫loadClass方法(雙親委派的具體邏輯實現)。但不建議這么做。

public class ClassLoaderTest extends ClassLoader {      private String classPath;      public ClassLoaderTest(String classPath) {         this.classPath = classPath;     }      /**      * 編寫findClass方法的邏輯      *      * @param name      * @return      * @throws ClassNotFoundException      */     @Override     protected Class<?> findClass(String name) throws ClassNotFoundException {         // 獲取類的class文件字節數組         byte[] classData = getClassData(name);         if (classData == null) {             throw new ClassNotFoundException();         } else {             // 生成class對象             return defineClass(name, classData, 0, classData.length);         }     }      /**      * 編寫獲取class文件并轉換為字節碼流的邏輯      *      * @param className      * @return      */     private byte[] getClassData(String className) {         // 讀取類文件的字節         String path = classNameToPath(className);         try {             InputStream is = new FileInputStream(path);             ByteArrayOutputStream stream = new ByteArrayOutputStream();             byte[] buffer = new byte[2048];             int num = 0;             // 讀取類文件的字節碼             while ((num = is.read(buffer)) != -1) {                 stream.write(buffer, 0, num);             }             return stream.toByteArray();         } catch (IOException e) {             e.printStackTrace();         }         return null;     }      /**      * 類文件的完全路徑      *      * @param className      * @return      */     private String classNameToPath(String className) {         return classPath + File.separatorChar                 + className.replace('.', File.separatorChar) + ".class";     }      public static void main(String[] args) {         String classPath = "/Users/zzs/my/article/projects/java-stream/src/main/java/";         ClassLoaderTest loader = new ClassLoaderTest(classPath);          try {             //加載指定的class文件             Class<?> object1 = loader.loadClass("com.secbro2.classload.SubClass");             System.out.println(object1.newInstance().toString());         } catch (Exception e) {             e.printStackTrace();         }     } }

到此,關于“Java中的ClassLoader核心知識點有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

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

AI

东乡族自治县| 山阳县| 永州市| 塘沽区| 友谊县| 锦州市| 林口县| 鄯善县| 石首市| 赞皇县| 潍坊市| 蕉岭县| 潞西市| 密云县| 聊城市| 天峨县| 尼勒克县| 泽州县| 县级市| 巴林右旗| 江都市| 利辛县| 衡阳县| 周宁县| 长岛县| 常山县| 唐海县| 泽普县| 射洪县| 绥芬河市| 牡丹江市| 天镇县| 苍梧县| 奈曼旗| 卢氏县| 安西县| 哈尔滨市| 文山县| 卢龙县| 连城县| 毕节市|