您好,登錄后才能下訂單哦!
這篇文章主要介紹“什么是JVM的類加載機(jī)制”,在日常操作中,相信很多人在什么是JVM的類加載機(jī)制問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對(duì)大家解答”什么是JVM的類加載機(jī)制”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
JVM中類的生命周期包括7個(gè)階段,加載、準(zhǔn)備、驗(yàn)證、解析、初始化、使用、卸載。其中準(zhǔn)備、驗(yàn)證、解析被歸為連接階段。
jvm在這個(gè)階段完成的工作
通過類名獲取類的二進(jìn)制字節(jié)流
將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
在堆中生成一個(gè)代表該類的java.lang.class
對(duì)象,作為訪問類在方法區(qū)中數(shù)據(jù)的入口
在這個(gè)階段開發(fā)者可以控制二進(jìn)制字節(jié)流的獲取,也就是可以通過自定義的類加載器做自己定制化的操作。
顧名思義,驗(yàn)證被加載的類的正確性。
文件格式驗(yàn)證:驗(yàn)證字節(jié)流是否符合Class文件格式的規(guī)范;例如:是否以 0xCAFEBABE開頭
元數(shù)據(jù)驗(yàn)證:對(duì)字節(jié)碼描述的信息進(jìn)行語義分析,以保證其描述的信息符合Java語言規(guī)范的要求
字節(jié)碼驗(yàn)證:通過數(shù)據(jù)流和控制流分析,確定程序語義是合法的、符合邏輯的。
符號(hào)引用驗(yàn)證:確保解析動(dòng)作能正確執(zhí)行
為類的 靜態(tài)變量分配內(nèi)存,并將其初始化為默認(rèn)值
只分配靜態(tài)變量內(nèi)存
初始化默認(rèn)值是類型的默認(rèn)值(即int:0、boolean:false...),不是代碼顯示設(shè)置的初始值
如果是final static
修飾的變量則會(huì)賦值為代碼中的初始值(即:final static int val=3,這時(shí)val賦值為3,而不是0)
把類中的符號(hào)引用轉(zhuǎn)換為直接引用符號(hào)引用就是一組符號(hào)來描述目標(biāo)(例如:ArrayList)。直接引用就是直接指向目標(biāo)的指針、相對(duì)偏移量或一個(gè)間接定位到目標(biāo)的句柄。
類變量的初始化
定義類變量時(shí)初始化
靜態(tài)代碼塊初始化
觸發(fā)類初始化的場(chǎng)景
創(chuàng)建類實(shí)例,即new對(duì)象
訪問靜態(tài)變量
訪問靜態(tài)方法
反射調(diào)用(即Class.forName("com.xxx.Obj"),Obj類被初始化)
子類被初始化則父類被初始化
啟動(dòng)類加載器(BootStrap ClassLoader):負(fù)責(zé)加載jrelib下或者-Xbootclasspath 參數(shù)指定的路徑下的能被jvm識(shí)別的類庫。開發(fā)者無法直接使用
拓展類加載器(Extension ClassLoader):sun.misc.Launcher$ExtClassLoader
,它負(fù)責(zé)加載 jrelibext目錄中,或者由 java.ext.dirs系統(tǒng)變量指定的路徑中的所有類庫。開發(fā)者可以直接使用。
應(yīng)用類加載器(Application ClassLoader):sun.misc.Launcher$AppClassLoader
,它負(fù)責(zé)加載用戶類路徑(ClassPath)所指定的類。開發(fā)者可以直接使用
自定義類加載器(Custom ClassLoader):用戶可以自定義類加載器
雙親委派模型的實(shí)現(xiàn),當(dāng)一個(gè)類加載器需要加載類時(shí),會(huì)把這個(gè)任務(wù)委派給父級(jí)類加載器,依次向上,倒頂層啟動(dòng)類加載器為止,如果父級(jí)無法加載,再自己處理加載。雙親委派模型的好處是,保證同一類環(huán)境中只有一個(gè)相同的類。也就是說JVM中判斷是否是同一個(gè)類的條件是,是否相同的類加載器,類本身相同。代碼示例:
public class ClassLoaderTest { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { // 使用ClassLoaderTest的類加載器加載本類 Object obj1 = ClassLoaderTest.class.getClassLoader().loadClass("com.ognice.ClassLoaderTest").newInstance(); System.out.println(obj1.getClass().getClassLoader()); System.out.println(obj1 instanceof ClassLoaderTest); // 使用自定義類加載器加載本類 ClassLoader customClassLoader = new ClassLoader() { @Override public Class<?> loadClass(String name) throws ClassNotFoundException { System.out.println("custom classloader loading " + name); String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class"; InputStream stream = getClass().getResourceAsStream(fileName); if (stream == null) { return super.loadClass(name); } try { byte[] b = new byte[stream.available()]; stream.read(b); return defineClass(name, b, 0, b.length); } catch (IOException e) { e.printStackTrace(); } // 父級(jí)找class return super.loadClass(name); } }; Object obj2 = customClassLoader.loadClass("com.ognice.ClassLoaderTest").newInstance(); System.out.println(obj2.getClass().getClassLoader()); System.out.println(obj2 instanceof ClassLoaderTest); } }
執(zhí)行結(jié)果
sun.misc.Launcher$AppClassLoader@18b4aac2 true custom classloader loading com.ognice.ClassLoaderTest custom classloader loading java.lang.Object custom classloader loading java.lang.ClassLoader custom classloader loading com.ognice.ClassLoaderTest$1 com.ognice.ClassLoaderTest$1@277c0f21 false
到此,關(guān)于“什么是JVM的類加載機(jī)制”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。