這篇文章主要講解了“java類加載器是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“java類加載器是什么”吧!
成都創(chuàng)新互聯(lián)從2013年開始,先為和平等服務(wù)建站,和平等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為和平企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
一.什么是類加載?
類加載器是一個(gè)加載類文件的java類,類加載器負(fù)責(zé)加載文件系統(tǒng),網(wǎng)絡(luò)或其他來源的類文件,java虛擬機(jī)將java編譯后的class文件(類描述文件),加載進(jìn)堆內(nèi)存中,并進(jìn)行校驗(yàn),轉(zhuǎn)換解析,初始化,最終形成虛擬機(jī)可識(shí)別的java類型。jvm中有三個(gè)默認(rèn)的類加載器,分別是根類加載器,擴(kuò)展類加載器和應(yīng)用類加載器。
二.類加載器干了些什么事情?
類加載器處理字節(jié)碼文件,java中,類加載器要將一個(gè)class文件裝入jvm中,需要以下步驟:
(1)裝載:查找和導(dǎo)入class文件;
(2)鏈接:
a.檢查:檢查載入的class文件是否正確:格式,語(yǔ)法等。
b.準(zhǔn)備:給靜態(tài)變量分配內(nèi)存空間
c.解析:將符號(hào)引用轉(zhuǎn)換成直接引用
(3初始化:對(duì)靜態(tài)變量和代碼塊進(jìn)行初始化
三.動(dòng)態(tài)加載和動(dòng)態(tài)鏈接什么時(shí)候會(huì)觸發(fā)?
java多態(tài)的特性,就是利用可以動(dòng)態(tài)的鏈接實(shí)現(xiàn)的,就是運(yùn)行時(shí)才知道它的具體實(shí)現(xiàn),所以解析過程還可以在初始化之后執(zhí)行,這個(gè)過程就是動(dòng)態(tài)綁定;
四.類的初始化方式有哪些?
(1)new ,getStatic,putStatic,invokeStatic 指令,都會(huì)觸發(fā)類的初始化
(2)java.long.reflect包的方法進(jìn)行反射調(diào)用 Class.forName("com.jd.xxxx")
(3)初始化子類也會(huì),先初始化父類
(4)調(diào)用類的靜態(tài)方法
(5)jvm的啟動(dòng)類,main方法的類
五.類加載器怎么裝載的?
(1)通過類名,找到對(duì)應(yīng)的二進(jìn)制字節(jié)流
(2)將字節(jié)流代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
(3)在堆內(nèi)存中生成代表這個(gè)類的對(duì)象,作為方法區(qū)訪問的入口
六.準(zhǔn)備階段做了哪些事?
(1)給靜態(tài)變量賦初始值,對(duì)于實(shí)例變量只會(huì)在對(duì)象初始化的時(shí)候?qū)χ鴮?duì)象一起分配到堆中
(2)初始值只是變量的默認(rèn)值,例如:public static final int = 123;這個(gè)時(shí)候只會(huì)初始化 0 ;
七.jvm的類加載是怎么加載的?
(1)依賴ClassLoader以及子類完成的。
(2)不同的ClassLoader,加載不同的模塊,而且有加載順序
(3)BootstrapClassLoader負(fù)責(zé)加載jre/lib/rt.jar下的所有包,或者-Xbootclasspath選項(xiàng)指定的jar包
(4)Extension ClassLoader 負(fù)責(zé)加載lib/ext/*.jar,也可以指定目錄Djava.ext.dirs
(5)AppClassLoader 加載classpath下的類或指定的類
(6)自定義類加載器,實(shí)現(xiàn)ClassLoader
八.自定義類加載器在哪里應(yīng)用?
如tomcat、jboss都會(huì)根據(jù)j2ee規(guī)范自行實(shí)現(xiàn)ClassLoader加載過程中會(huì)先檢查類是否被已加載,檢查順序是自底向上,從Custom ClassLoader到BootStrap ClassLoader逐層檢查,只要某個(gè)classloader已加載就視為已加載此類,保證此類只所有ClassLoader加載一次。而加載的順序是自頂向下,也就是由上層來逐層嘗試加載此類
九.什么是雙親委托
1.子類加載器會(huì)首先委托父類加載器去加載,逐層往上進(jìn)行檢查加載。
2.所以從上往下,bootStrap類加載器會(huì)先看看rt.jar中有沒有該類,再看extension類加載器有沒有加載該類,有則Application類加載器不需要加載classpath類文件加載目錄。
注意:BootStrap ClassLoader并不屬于JVM的類等級(jí)層次,它沒有遵循ClassLoader的加載規(guī)則它也沒有子類。JVM能提取到的頂層父類是ClassLoader,然后URLClassLoader實(shí)現(xiàn)了該抽象類而ExtClassLoader和AppClassLoader都繼承了URLClassLoader,不過他們是sun.miss.Launcher的內(nèi)部類,所以創(chuàng)建Launcher類是會(huì)創(chuàng)建ExtClassLoader ,然后ExtClassLoader作為父加載器創(chuàng)建AppClassLoader。
十.類加載器的工作原理:
1.原理基于三個(gè)機(jī)制:委托,可見性和單一性
2.委托就是子類加載器會(huì)委托父類加載器;可見性就是子類可以看見父類加載的類,父類卻看不到子類:如果一個(gè)類被子類加載,則父類再去加載該類會(huì)拋出ClassNotFundException異常; 單一性原理是指僅加載一個(gè)類一次,這是由委托機(jī)制確保子類加載器不會(huì)再次加載父類加載器加載過的類。
備注:雖然重寫違反委托和單一性機(jī)制的類加載器是可能的,但這樣做并不可取。你寫自己的類加載器的時(shí)候應(yīng)該嚴(yán)格遵守這三條機(jī)制
十一.如何自己實(shí)現(xiàn)一個(gè)類加載器
a.加載自定義路勁下的文件:
思路:1.繼承ClassLoader類,指定ClassPath路勁,重寫findClass文件,如果不是自定義的class目錄仍然使用父類加載。2.繼承URLClassLoader類,自定義一個(gè)Url,然后調(diào)用findClass(url);
b.加載自定義格式的Class,加密解密等網(wǎng)絡(luò)傳輸接受的文件。
思路:獲取網(wǎng)絡(luò)傳輸流,解密還原類文件格式。通過ClassLoader的defineClass()創(chuàng)建這個(gè)類的實(shí)例
十二.問題和思考:
a.如何實(shí)現(xiàn)一個(gè)熱部署?
b.程序運(yùn)行時(shí)動(dòng)態(tài)加載類會(huì)有什么問題?
c.熱部署時(shí)JVM中的對(duì)象如何平滑過渡?
例子:嘗試用戶父加載器進(jìn)行類再次加載,會(huì)拋出異常,驗(yàn)證單一性。其他的可以自己試一試
感謝各位的閱讀,以上就是“java類加載器是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)java類加載器是什么這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!