未能成功加载扩展程序_【JAVA虚拟机(JVM)精髓】09-几种不同的类加载器
持續(xù)更新JVM相關(guān)知識,敬請關(guān)注:
Java虛擬機(jī)精髓專欄?zhuanlan.zhihu.com
上一節(jié)說了下類加載器和類加載過程。這一節(jié)我們看下幾種不同的類加載器。
JVM支持的類加載器有兩類,分別是引導(dǎo)類加載器和自定義加載器。這里的自定義自定義加載器,不僅僅指用戶自己實(shí)現(xiàn)的加載器,而是泛指所有繼承ClassLoader這個抽象類的加載器。
作為JAVA程序員,起碼要知道引導(dǎo)加載器、擴(kuò)展加載器、系統(tǒng)加載器這三種,除此之外,還有很多用戶自定義加載器,他們的分類關(guān)系見下圖。
JAVA內(nèi)部實(shí)際的繼承關(guān)系如何呢?大家可以查看下Laucher類,會發(fā)現(xiàn)其中有兩個內(nèi)部類,ExtClassLoader和AppClassLoader,這兩個就是擴(kuò)展類加載器和系統(tǒng)類加載器。他們都繼承自URLClassLoader,URLClassLoader再繼承自SecureClassLoader,最終繼承ClassLoader。下面我們來看一個代碼實(shí)例:
首先我們通過ClassLoader提供的方法直接獲取系統(tǒng)類加載器,會發(fā)現(xiàn)是AppClassLoader,然后我們再通過getParent方法,獲取上層擴(kuò)展類加載器,發(fā)現(xiàn)是ExtClassLoader,之后我們再想getParent獲取引導(dǎo)類加載器,發(fā)現(xiàn)獲取不到了,輸出了null。
下面我們通過當(dāng)前類的類對象,獲取他的ClassLoader,輸出的是AppClassLoader,說明當(dāng)前類是由系統(tǒng)類加載器加載的,并且大家注意,這個系統(tǒng)類加載器同之前那個內(nèi)存地址是一致的,有此可見,這個系統(tǒng)類加載器只會被加載一次。
最后我們再看下String類的加載器,發(fā)現(xiàn)輸出的是null,這就說明了,String加載器是通過引導(dǎo)類加載器加載的。系統(tǒng)的核心類庫,都是使用引導(dǎo)類加載的。
下面我們來具體說下這幾種不同的加載器:
1、引導(dǎo)類加載器(Bootstrap ClassLoader)
引導(dǎo)類加載器是由C和C++語言實(shí)現(xiàn)的,集成在JVM內(nèi)部,所有JAVA的核心類庫(rt.jar、resources.jar、sun.boot.class.path等)通過它來加載的。引導(dǎo)類加載器不繼承java.lang.ClassLoader也沒有上層加載器。他是擴(kuò)展類加載器和應(yīng)用類加載器的父類。Java由于安全方面的考慮,引導(dǎo)類加載器,只能加載java、javax、sun為開頭的java自身的類庫。
我們通過代碼雖然獲取不到引導(dǎo)類加載器,但是我們可以查看下可以加載哪些類庫:
import可以看到輸出結(jié)果如下:
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/resources.jar /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/rt.jar /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/sunrsasign.jar /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jsse.jar /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jce.jar /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/charsets.jar /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jfr.jar /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/classes2、擴(kuò)展類加載器(Extension ClassLoader)
擴(kuò)展類加載器,是JVM內(nèi)部自帶的加載器,Java語言編寫,對應(yīng)sun.misc.Launcher$ExtClassLoader這個內(nèi)部類。間接繼承自ClassLoader類,他是通過引導(dǎo)類加載器進(jìn)行加載的。擴(kuò)展類加載器負(fù)責(zé)加載java.ext.dirs所指定目錄或jre/libb/ext中的類庫,我們自己定義的jar放到這些路徑下,就會被擴(kuò)展類加載器所加載。
3、系統(tǒng)類加載器(System ClassLoader)
系統(tǒng)類加載器,也叫做應(yīng)用程序加載器,也是由JAVA語言編寫的,對應(yīng)sun.misc.Launcher$AppClassLoader這個內(nèi)部類。同樣間接繼承ClassLoader類,它是通過擴(kuò)展類加載器加載的。系統(tǒng)類加載器負(fù)責(zé)加載classpath路徑下或java.class.path屬性下的指定的了類庫。實(shí)際上,系統(tǒng)類加載器是程序中的默認(rèn)加載器,我們平常所編寫的絕大不部分類,默認(rèn)都是由這個加載器所加載的。這個可以看上面的代碼演示結(jié)果。代碼中,我們可以通過ClassLoader提供的getSystemClassLoader()方法獲得到這個類加載器的實(shí)例。
4、用戶自定義類加載器(User Defined ClassLoader)
在某些場合下,我們使用上述三種類加載器,無法滿足我們的使用需求,這是就需要由我們自己去自定義一些類加載器,當(dāng)然,這個在一般應(yīng)用場景下會比較少用,所以在這不做過多講解,之后再去詳細(xì)說。用戶可以通過繼承ClassLoader,jdk1.2以后,可以重寫findClass方法來實(shí)現(xiàn)自定義,這里主要編寫的邏輯是加載對應(yīng)路徑的類的二進(jìn)制數(shù)組,然后調(diào)用defineClass()方法去生成傳入字節(jié)數(shù)組所代表類的實(shí)例。這里面對二進(jìn)制數(shù)組的特殊操作,就可以根據(jù)需求去做更改了。如果需求更加簡潔,也可以直接繼承URLClassLoader來實(shí)現(xiàn)。
總結(jié)
以上是生活随笔為你收集整理的未能成功加载扩展程序_【JAVA虚拟机(JVM)精髓】09-几种不同的类加载器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python绘制条形图例题_python
- 下一篇: 云盾idaas登陆_移动端扫码登录IDa