類加載器

三種系統提供的類加載器:

  1. 啓動類加載器(Bootstrap):這個類加載器負責將放在JAVA_HOME/lib目錄下的類庫記載到虛擬機內存中,這個加載器無法被程序引用
  2. 擴展類加載器(Extension):由sun.misc.Launcher$ExtClassLoader實現,負責加載JAVA_HOME/lib/ext目錄或者java.ext.dirs指定的路徑的類庫
  3. 應用程序類加載器(Application):由sun.misc.Launcher$AppClassLoader實現,負責加載用戶類路徑上指定的類庫(CLASSPATH指定的類庫),一般情況下這個就是程序中默認的類加載器

加載路徑簡單描述:

BootStrap –>JRE/lib/rt.jar
ExtClassLoader–>JRE/lib/ext/*.jar
AppClassLoader–>CLASSPATH指定的所有jar或目錄
(配置環境變量,讓AppClassLoader這個類加載器能去加載我們寫的類)

雙親委派模型

如果一個類加載器收到了類加載的請求,首先不會自己去嘗試加載這個類,而是把請求委派給父類加載器去完成,如果父類加載器無法無法完成這個加載請求,子類加載器纔會嘗試自己去加載,這是推薦的類加載器模型

問題:能不能自己寫一個類加載java.lang.System?

回答:類加載採用委託機制,總是保證父類優先與子類,也就是如果父類找到了你委託它加載的類,那麼它直接把加載完的字節碼給你,由於BootStrap(啓動類加載器)可以加載rt.jar下面有System這個類,所以總是由BootStrap來加載System類,而不是用我們自己編寫的類加載器來加載.

代碼例子

      /*
       * 類加載器有3個: BootStrap,ExtClassLoader,AppClassLoader
       */
      System.out.println(test.class.getClassLoader().getClass().getName());
// 打印出AppClassLoader,由AppClassLoader加載的
System.out.println(System.class.getClassLoader());
// 打印出null,由BootStrap加載的

// 測試3個類加載器的父子關係
ClassLoader loader = test.class.getClassLoader();
while(loader !=null) {
    System.out.println(loader.getClass().getName());
    loader = loader.getParent();
}
System.out.println(loader);
      /*
       * 打印出AppClassLoader----的父類-->ExtClassLoader----的父類-->BootStrap,
       * BootStrap是最頂部的類加載 
       */
發佈了81 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章