Java的類加載器有幾種?什么是雙親委派機制?


一、JAVA類加載器包括幾種?

啟動類加載器 bootstrap class loader

  啟動類加載器主要加載的是JVM自身需要的類,這個類加載是用C++語言實現的,是虛擬機自身的一部分,它負責將 /lib路徑下的核心類庫或-Xbootclasspath參數指定的路徑下的jar包加載到內存中,注意:由於虛擬機是按照文件名識別加載jar包的,如rt.jar,如果文件名不被虛擬機識別,即使把jar包丟到lib目錄下也是沒有作用的(出於安全考慮,Bootstrap啟動類加載器只加載包名為java、javax、sun等開頭的類)。

擴展類加載器 extensions class loader

  它負責加載JAVA_HOME/lib/ext目錄下或者由系統變量-Djava.ext.dir指定位路徑中的類庫,開發者可以直接使用標准擴展類加載器。

應用程序類加載器 application class loader

  應用程序加載器是指 Sun公司實現的sun.misc.Launcher$AppClassLoader。它負責加載系統類路徑java -classpath或-D java.class.path 指定路徑下的類庫,也就是我們經常用到的classpath路徑,開發者可以直接使用系統類加載器,一般情況下該類加載是程序中默認的類加載器,通過ClassLoader#getSystemClassLoader()方法可以獲取到該類加載器。

自定義類加載器 java.lang.classloder

  自定義類加載器需要繼承java.lang.ClassLoader。

類加載器之間的關系

  啟動類加載器,由C++實現,沒有父類。    

  拓展類加載器(ExtClassLoader),由Java語言實現,父類加載器為null    

  系統類加載器(AppClassLoader),由Java語言實現,父類加載器為ExtClassLoader    

  自定義類加載器,父類加載器肯定為AppClassLoader。

二、雙親委派機制

  請注意雙親委派模式中的父子關系並非通常所說的類繼承關系。    

  其工作原理的是:如果一個類加載器收到了類加載請求,它並不會自己先去加載,而是把這個請求委托給父類的加載器去執行,如果父類加載器還存在其父類加載器,則進一步向上委托,依次遞歸,請求最終將到達頂層的啟動類加載器,如果父類加載器可以完成類加載任務,就成功返回,倘若父類加載器無法完成此加載任務,子加載器才會嘗試自己去加載,這就是雙親委派模式,即每個兒子都很懶,每次有活就丟給父親去干,直到父親說這件事我也干不了時,兒子自己想辦法去完成。

雙親委派機制作用/好處

  通過這種層級關可以避免類的重復加載,當父親已經加載了該類時,就沒有必要子ClassLoader再加載一次。其次是考慮到安全因素,java核心api中定義類型不會被隨意替換,假設通過網絡傳遞一個名為java.lang.Integer的類,通過雙親委托模式傳遞到啟動類加載器,而啟動類加載器在核心Java API發現這個名字的類,發現該類已被加載,並不會重新加載網絡傳遞的過來的java.lang.Integer,而直接返回已加載過的Integer.class,這樣便可以防止核心API庫被隨意篡改。

  總結:

  好處1、可以防止類的重復加載

  好處2、可以防止Java核心api類庫被篡改

應用場景

  如Tomcat容器,每個WebApp有自己的ClassLoader,加載每個WebApp的ClassPath路徑上的類,一旦遇到Tomcat自帶的Jar包就委托給CommonClassLoader加載。同包的隔離。另外成熟的開源框架,都有自己的ClassLoader。


免責聲明!

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



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