類加載器的作用
將class文件字節(jié)碼內(nèi)容加載到內(nèi)存中,并將這些講臺數(shù)據(jù)轉(zhuǎn)換成方法區(qū)中的運行時數(shù)據(jù)結(jié)構(gòu),在堆中生產(chǎn)一個代表這個類的
java.lang.Class對象,作為方法區(qū)類數(shù)據(jù)的訪問入口。
類緩存
- 標(biāo)準(zhǔn)的java se類加載器可以按要求查找類,但一旦某個類被加載到類加載器中,它將維持加載(緩存)一段時間,不過,JVM垃圾收集器可以回收這些Class對象。
類加載器的層次結(jié)構(gòu)(樹狀結(jié)構(gòu))
1. 引導(dǎo)類加載器(bootstrap class loader)
- 它用來加載java的核心庫(
JAVA_HOME/jre/lib/rt.jar,或sun.boot.class.path路徑下的內(nèi)容),是用原生代碼來實現(xiàn)的,并不繼承自java.lang.ClassLoader.- 加載擴展類和引用程序加載器。并制定他們的父類加載器。
2. 擴展類加載器(extensions class loader)
- 用來加載java的擴展庫(
JAVA_HOME/jre/ext/*.jar,或java.ext.dirs路徑下的內(nèi)容)。java虛擬機的實現(xiàn)會提供一個擴展庫目錄。該類加載器在此目錄里面查找并加載java類。- 由
sun.misc.Launcher$ExtClassLoader實現(xiàn)
3. 應(yīng)用程序類加載器(application class loader)
- 它根據(jù)java應(yīng)用的類路徑(classpath,java.class.path路徑類)一般來說,java應(yīng)用的類都是由它來完成加載的。
- 由
sun.misc.Launcher$AppClassLoader實現(xiàn)
4. 自定義類加載器
- 開發(fā)人員可以通過繼承
java.lang.ClassLoader類的方式實現(xiàn)自己的類加載器,以滿足一些特殊的需求。
java.class.ClassLoader類介紹
作用:
- java.lang.Classloader類的基本職責(zé)就是根據(jù)一個指定的類的名稱,找到或者生產(chǎn)其對應(yīng)的字節(jié)代碼,然后從這些字節(jié)diamante定義出一個java類,即
java.lang.Class類的一個實例。- 除此之外,ClassLoader還負責(zé)加載java應(yīng)用所需的資源,如圖像文件和配置文件等。
相關(guān)方法:
- getParent() 返回該類加載器的類加載器
loadClass(String name) 加載名稱為name的類,返回的記過是java.lang.Class類的實例。
1.此方法負責(zé)加載指定名字的類,首先會從已加載的類中去尋找,如果沒有找到;從parent ClassLoader[ExtClassLoader]中加載;如果沒有加載到,則從Bootstrap classLoader 中嘗試加載(findBootstrapClasOrNull方法),如果還是加載失敗,則自己加載。如果還不能加載,則拋出異常ClassNotFoundException.
2.如果要改變類的加載順序可以覆蓋此方法;
findClass(String name) 查找名稱為name的類,返回結(jié)果是java.lang.Class類的實例。
findLoaderdClass(String name) 查找名稱為name的已經(jīng)被加載過的類,返回的結(jié)果是java.lang.Class類的實例。
defineClass(String name ,byte[] b, int off, int len) 把字節(jié)數(shù)組b的內(nèi)容轉(zhuǎn)換成java類,返回的結(jié)果是java.lang.Class類的實例,這個方法被聲明為final的。
resolveClass(Class<?> c) 鏈接指定的java類。- 對于以上給出的方法,表示類名稱的name參數(shù)的值是類的二進制名稱。需要注意的是內(nèi)部的表示,如
com.example.Sample$1和com.example.Sample$Inner等表示方式。
類加載器的代理模式
代理模式
- 交給其他加載器來加載指定的類。
雙親委托機制
就是某個特定的類加載器在接到加載類的請求時,首先將加載任務(wù)委托給父類加載器,以此追溯,知道最高的爺爺輩的,如果父類加載器可以完成類加載任務(wù),就成功返回;只有父類加載器無法完成此加載任務(wù)時,才自己去加載。
雙親委托機制是為了保證java核心庫的類型安全。
這種機制就保證不會出現(xiàn)用戶自己能定義java.lang.Object類的情況類加載器除了用于加載類,也是安全的最基本的屏障。
雙親委托機制是代理模式的一種
- 并不是所有的類加載器都采用雙親委托機制。
- Tomcat服務(wù)器類加載器也使用代理模式,所不同的是它是首先嘗試去加載某個類,如果找不到再代理給父類加載器。這與一般類加載器的順序是相反的。