您好,登錄后才能下訂單哦!
今天小編給大家分享一下Java的雙親委派模式怎么實(shí)現(xiàn)的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
說起雙親委派模型,不得不說一下類加載器。
當(dāng)我們編譯Java類時(shí),JVM會(huì)創(chuàng)建與平臺(tái)和機(jī)器無關(guān)的字節(jié)碼。字節(jié)碼存儲(chǔ)在.class
文件中。當(dāng)我們嘗試使用一個(gè)類時(shí),類加載器就會(huì)把它加載到內(nèi)存中,然后把字節(jié)碼文件轉(zhuǎn)成Class對(duì)象。通俗的說類加載器就是將.class
文件轉(zhuǎn)成Class對(duì)象的。
啟動(dòng)類加載器(Bootstrap Class Loader):負(fù)責(zé)加載存放在 <JAVA_HOME>\lib
目錄下的類,或者被-Xbootclasspath
參數(shù)所指定的路徑中存放的類。比如:rt.jar
、java.lang.*
包下的類。
擴(kuò)展類加載器(Extension Class Loader):負(fù)責(zé)加載<JAVA_HOME>\lib\ext
目錄中,或者被java.ext.dirs
系統(tǒng)變量所指定的路徑中所有的類庫。
應(yīng)用程序類加載器(Application Class Loader):負(fù)責(zé)加載用戶類路徑上所有的類庫。
當(dāng)類加載器收到加載類的請(qǐng)求時(shí),它首先會(huì)把請(qǐng)求委派給父加載器去完成,每一層都如此,直到把請(qǐng)求委派給最頂層的啟動(dòng)類加載器,只有當(dāng)父加載器無法加載委派過來的類時(shí),子加載器才會(huì)加載。
JVM在加載?個(gè)類時(shí),會(huì)調(diào)?AppClassLoader的loadClass
?法來加載這個(gè)類,不過在這個(gè)?法中,會(huì)先使?ExtClassLoader的loadClass
?法來加載類,同樣ExtClassLoader的loadClass
?法中會(huì)先使?BootstrapClassLoader來加載類,如果BootstrapClassLoader加載到了就直接成功,如果 BootstrapClassLoader沒有加載到,那么ExtClassLoader就會(huì)??嘗試加載該類,如果沒有加載到,那么則會(huì)由AppClassLoader來加載這個(gè)類。
所以,雙親委派指得是,JVM在加載類時(shí),會(huì)委派給ExtClassLoader和BootstrapClassLoader進(jìn)?加載,如果沒加載到才由??進(jìn)?加載。
這里說的雙親并不是說類加載器之間是以繼承方式實(shí)現(xiàn)的,而是以組合的方式實(shí)現(xiàn)的,通過源碼可以證實(shí)這點(diǎn):
java.lang.ClassLoader#loadClass
private final ClassLoader parent; protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
同時(shí),通過源碼我們也可以看到類加載器的加載流程是跟我們描述的一樣的:先檢查請(qǐng)求加載的類型是否已經(jīng)被加載過,若沒有則調(diào)用父加載器的loadClass()
方法,若父加載器為空則默認(rèn)使用啟動(dòng)類加載器作為父加載器。假如父類加載器加載失敗,拋出ClassNotFoundException
異常的話,才調(diào)用自己的findClass()
方法嘗試進(jìn)行加載。
保證唯一性,避免重復(fù)加載:類的加載隨著它的類加載器一起具備了層級(jí)關(guān)系,通過這種層級(jí)關(guān)系避免了重復(fù)加載,父類加載器加載了該類,子加載器就無需加載了。
避免核心類被篡改:核心類由啟動(dòng)類加載器加載,即使用戶自定義同名核心類也不會(huì)被加載。
以上就是“Java的雙親委派模式怎么實(shí)現(xiàn)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。