您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家?guī)碛嘘PJVM虛擬機中Class文件的常量池是什么,文章內容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
在class文件中的魔數(shù)、副版本號、主版本之后,緊接著就是常量池的數(shù)據(jù)區(qū)域了,如下圖用紅線包括的位置:
常量池可以比喻為Class文件里的資源倉庫,它是Class 文件結構中與其他項目關聯(lián)最多的數(shù)據(jù),通常也是占用Class文件空間最大的數(shù)據(jù)項目之一,另外,它還是在Class文件中第一個出現(xiàn)的表類型數(shù)據(jù)項目。
常量池的結構比較簡單,前面的兩個字節(jié)叫做常量池計數(shù)器(constantpoolcount),它記錄了常量池項(cpinfo)的個數(shù)。后面緊接著就是constantpoolcount-1個常量池項(cpinfo)。這跟報文通信協(xié)議比較類似,首先定義報文的大小,接著就是對應大小的報文內容。
由于常量池中常量的數(shù)量是不固定的,所以在常量池的入口需要放置一項u2類型的數(shù)據(jù),代表常量池容量計數(shù)值(constantpoolcount)。與Java中語言習慣不同,這個容量計數(shù)是從1而不是0開始的,如上圖所示,常量池容量(偏移地址:0x00000008)為十六進制數(shù)0x0021,即十進制的33,這就代表常量池中有33項常量,索引值范圍為1~33。在Class文件格式規(guī)范制定之時,設計者將第0項常量空出來是有特殊考慮的,這樣做的目的在于,如果后面某些指向常量池的索引值的數(shù)據(jù)在特定情況下需要表達“不引用任何一個常量池項目”的含義,可以把索引值設置為0來表示。Class文件結構中只有常量池的容量計數(shù)是從1開始,對于其他集合類型,包括接口索引集合、字段表集合、方法表集合等的容量計數(shù)都與一般習慣相同,是從0開始。
常量池中主要存放兩大類常量: 字面量(Literal)和符號引用(SymbolicReferences)
。字面量比較接近于Java語言層面的常量概念,如文本字符串、被聲明為final的常量值等;而符號引用則屬于編譯原理方面的概念。具體分類如下圖:
常量池中每一項常量都是一個表,最初常量表中共有11種結構各不相同的表結構數(shù)據(jù),后來為了更好地支持動態(tài)語言調用,額外增加了4種動態(tài)語言相關的常量,為了支持Java模塊化系統(tǒng) (Jigsaw),又加入了CONSTANTM oduleinfo和CONSTANTPackageinfo兩個常量,所以截至JDK 13,常量表中分別有17種不同類型的常量。這17類表都有一個共同的特點,表結構起始的第一位是個u1類型的標志位(tag,取值見下表中標志列),代表著當前常量屬于哪種常量類型。
官網(wǎng)最新:http://cr.openjdk.java.net/~jrose/jvm/constant-dynamic-jrose.html
我們對這個class文件進行分析,可以看到前8個字節(jié)是該class文件的魔數(shù)和版本號,緊接著的一個十六進制數(shù)0x0021,即十進制的33,這就代表z這個class文件的常量池中有32項常量,索引值為1~32。然后就是第一個常量了,上面說過,每種類型的常量開始的第一位都是一個u1類型的標志位,代表該常量的類型,這里是0x0a,十進制的10,查上面的表可知是CONSTANTMethodrefinfo,說明這個常量是類中方法的符號應用。該類型常量的具體結構為:
第一個index值為0x0004,即指向常量池中的第4個常量,第二個index是0x0019,即指向常量池中的第25個常量。在JDK的bin目錄中,Oracle公司已經(jīng)為我們準備好一個專門用于分析Class文件字節(jié)碼的工具:javap。我們可以用javap -verbose命令查看class文件的字節(jié)碼內容。
可以看到和我們分析的一致,該class文件中確實有32項常量,從#1到#32。
上述就是小編為大家分享的JVM虛擬機中Class文件的常量池是什么了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。