java classloader雙親委派原則


1.1  class loader

1.1.1    加載器類型

1.1.1.1  bootstrap class loader

引導類加載器/啟動類加載器,用來加載java的核心庫。主要是 jre/lib目錄(來源於環境變量sun.boot.class.path)。其由c++編寫,本身屬於虛擬機的一部分,無法在java代碼中獲取它的引用。

打印其啟動的jar:

    String[] files = System.getProperty("sun.boot.class.path").split(";");

    Arrays.asList(files).forEach(System.out::println);   

結果:

    C:\Program Files\Java\jdk1.8.0_151\jre\lib\endorsed\rt_debug.jar (自己添加的debug時用於顯示變量的rt.jar)

C:\Program Files\Java\jdk1.8.0_151\jre\lib\resources.jar

C:\Program Files\Java\jdk1.8.0_151\jre\lib\rt.jar

C:\Program Files\Java\jdk1.8.0_151\jre\lib\sunrsasign.jar

C:\Program Files\Java\jdk1.8.0_151\jre\lib\jsse.jar

C:\Program Files\Java\jdk1.8.0_151\jre\lib\jce.jar

C:\Program Files\Java\jdk1.8.0_151\jre\lib\charsets.jar

C:\Program Files\Java\jdk1.8.0_151\jre\lib\jfr.jar

C:\Program Files\Java\jdk1.8.0_151\jre\classes

 

1.1.1.2  extensions class loader

擴展類加載器,用來加載java的擴展庫

打印其啟動的jar

    String[] extFiles = System.getProperty("java.ext.dirs").split(";");

    Arrays.asList(extFiles).forEach(System.out::println); 

結果:

C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext

C:\Windows\Sun\Java\lib\ext

1.1.1.3  system class loader/application class loader

系統類加載器

打印其啟動的jar

    String[] appFiles = System.getProperty("java.class.path").split(";");

    Arrays.asList(appFiles).forEach(System.out::println); 

結果:

E:\work_space\Study\target\test-classes

E:\work_space\Study\target\classes

D:\mvn_repositroy\org\slf4j\slf4j-api\1.7.22\slf4j-api-1.7.22.jar

D:\mvn_repositroy\ch\qos\logback\logback-core\1.1.8\logback-core-1.1.8.jar

D:\mvn_repositroy\ch\qos\logback\logback-classic\1.1.8\logback-classic-1.1.8.jar

1.1.1.4  自定義加載器

1.1.2    類加載器之間的關系

  除了引導類加載器,所有的類加載器都有一個父類加載器。

  默認情況下,開發人員自己編寫的類加載器父類加載器是系統類加載器(除非顯示指定了父類加載器)。可以通過getParent()獲得(除了父類為引導類加載器)。示意圖如下:

 

  

 

 

   

1.1.3    雙親委托

java虛擬機是如何判定兩個class是相同的:不僅要看類的全名是否相同,還要看加載器是否相同。

比如Hello.class是編譯后的字節碼,如果不自定義加載器,那么只會加載一次這個class,但是如果自定義了兩個同級classloader,那么則可以加載兩個class。

雙親委托主要概念見下圖,設計思想主要是避免同一個類被不同的加載器加載,導致額外問題。

加載類之前先看看父類有沒有,沒有的話看看父類能不能加載,父類有的直接復用,父類能加載的自己絕不加載。(自定義類加載器除外,某些時刻屬於定制加功能)

1.1.3.1  示意圖

   

  

  

 

1.1.4    參考資源

https://blog.csdn.net/briblue/article/details/54973413

https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html

https://www.jianshu.com/p/6e5c2b463b2a

備注:圖都是摘錄的,理論上來源於上面三個鏈接。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM