類(lèi)文件結(jié)構(gòu)
虛擬機(jī)在對(duì)編譯代碼的時(shí)候會(huì)產(chǎn)生字節(jié)碼的文件萎胰,也就是class文件,這個(gè)字節(jié)碼文件的產(chǎn)生是java虛擬機(jī)實(shí)戰(zhàn)跨平臺(tái)語(yǔ)言操作的重要原因。
首先扣汪,這個(gè)class文件是一組由8個(gè)字節(jié)為基礎(chǔ)單位的二進(jìn)制流。它里面依次包括魔數(shù)和class文件版本科平、常量池褥紫、訪問(wèn)標(biāo)志、類(lèi)索引瞪慧、父類(lèi)索引與接口索引集合髓考、字段表集合、方法表集合汞贸、屬性表集合
重點(diǎn)理解常量池和字段表
常量池:class文件的資源倉(cāng)庫(kù)绳军,為什么這么說(shuō)呢?因?yàn)樗锩娲娣胖芏喑A渴改澹ㄗ置媪亢头?hào)引用门驾,這些常量主要是:類(lèi)和接口的全限定名、字段的名稱和描述符多柑、方法的名稱和描述符奶是。在之后的方法表和屬性表都會(huì)根據(jù)符號(hào)引用找到對(duì)應(yīng)的字面值
舉個(gè)例子,你在字段表中知道了該字段的作用域竣灌、字段名稱聂沙,它是通過(guò)標(biāo)志位來(lái)描述的,然后你通過(guò)這個(gè)標(biāo)志位去引用常量池中對(duì)應(yīng)的常量
常量池的每一個(gè)常量都是一個(gè)表
字段表與方法表以及索引集合初嘹、屬性表集合都是類(lèi)似的及汉,都是一些固定的指標(biāo)位分別來(lái)描述字段、方法屯烦、索引坷随、屬性,再或者就是各自特定的信息(通過(guò)標(biāo)志位的引用找到常量池方法)
類(lèi)加載機(jī)制
虛擬機(jī)在運(yùn)行程序的時(shí)候驻龟,需要將之前編譯好的class文件加載到內(nèi)存温眉,而這個(gè)class文件包括了描述類(lèi)的所有數(shù)據(jù),所以虛擬機(jī)之后還會(huì)對(duì)這些數(shù)據(jù)進(jìn)行處理
總的來(lái)說(shuō)翁狐,虛擬機(jī)加載機(jī)制為:加載class文件类溢、對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)、轉(zhuǎn)換解析露懒、然后初始化闯冷,最終形成java類(lèi)型
虛擬機(jī)要進(jìn)行加載是需要特定的時(shí)機(jī)的,也就是說(shuō)需要特定的一些指令懈词。比如在遇到new 窃躲、getstatic等指令就會(huì)進(jìn)行加載;當(dāng)對(duì)類(lèi)進(jìn)行反射調(diào)用,若類(lèi)沒(méi)有初始化钦睡,需要進(jìn)行加載使其初始化;初始化子類(lèi)時(shí)蒂窒,父類(lèi)沒(méi)初始化躁倒,會(huì)先初始化父類(lèi);執(zhí)行主類(lèi)(main)時(shí)會(huì)初始化;jdk1.7動(dòng)態(tài)語(yǔ)言,對(duì)方法句柄解析結(jié)果之前要先初始化洒琢。之上的叫做類(lèi)的主動(dòng)引用
類(lèi)加載的過(guò)程
加載:
1秧秉、獲取該類(lèi)二進(jìn)制字節(jié)流(找到該類(lèi)對(duì)應(yīng)的class文件)
2、把字節(jié)流的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)運(yùn)行時(shí)的數(shù)據(jù)結(jié)構(gòu)
3衰抑、在內(nèi)存中生成這個(gè)類(lèi)的java.lang.class對(duì)象
驗(yàn)證:
驗(yàn)證該class文件能被虛擬機(jī)識(shí)別讀认笥(我猜想會(huì)跟字節(jié)碼文件中的魔數(shù)有關(guān)),并不會(huì)危害虛擬機(jī)
準(zhǔn)備:
為類(lèi)變量(static變量)分配內(nèi)存
解析:
將常量池中的符號(hào)引用變?yōu)橹苯右?/p>
初始化:
執(zhí)行類(lèi)構(gòu)造器方法
雙親委派模型
類(lèi)加載在加載類(lèi)的時(shí)候呛踊,一開(kāi)始并不是自己加載砾淌,而是讓這個(gè)類(lèi)的父類(lèi)加載器去加載,以此類(lèi)推谭网,就能確保每個(gè)層次的類(lèi)加載器都是由頂層啟動(dòng)類(lèi)加載器完成的時(shí)候除非父類(lèi)加載器無(wú)法完成子類(lèi)的加載
雙親委派模型確保了每個(gè)相同的類(lèi)加載出來(lái)的類(lèi)屬于同一個(gè)類(lèi)汪厨,因?yàn)椴煌念?lèi)加載器會(huì)導(dǎo)致多個(gè)object實(shí)例對(duì)象為不同的Object對(duì)象,無(wú)法保證java體系最基礎(chǔ)的繼承等行為愉择。所以雙親委派模型保證了java程序運(yùn)作的穩(wěn)定性