這篇文章將為大家詳細(xì)講解有關(guān)如何理解Java Class文件常量池,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
10余年的青川網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整青川建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“青川網(wǎng)站設(shè)計(jì)”,“青川網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
Class文件的存在使得不同語言編寫的程序都可以運(yùn)行在Java虛擬機(jī)上,只需要這些語言經(jīng)過編譯器編譯后的Class文件符合Java虛擬機(jī)定義的規(guī)范,Java虛擬機(jī)就可以加載執(zhí)行這些Class文件。如下圖所示:
Class文件是一組以8位字節(jié)為基礎(chǔ)單位的二進(jìn)制流,各個(gè)數(shù)據(jù)項(xiàng)目嚴(yán)格按照順序緊湊地排列在Class文件中,當(dāng)遇到需要占用8個(gè)字節(jié)以上空間的數(shù)據(jù)是,則按照大端序的方式分割成若干個(gè)8位字節(jié)進(jìn)行存儲(chǔ)。
Class文件中只存在兩種數(shù)據(jù)類型:
無符號(hào)數(shù)屬于基本數(shù)據(jù)類型,以u(píng)1、u2、u4、u8分別表示1個(gè)、2個(gè)、4個(gè)和8個(gè)字節(jié)的無符號(hào)數(shù),無符號(hào)數(shù)可以用來描述數(shù)字、索引引用、數(shù)量值或者按照UTF-8編碼構(gòu)成的字符串值。
表是由無符號(hào)數(shù)和其他表組成的數(shù)據(jù)結(jié)構(gòu),所有的表都以_info結(jié)尾。
當(dāng)在描述一個(gè)可變長度的類型數(shù)據(jù)時(shí),通常會(huì)采用一個(gè)容量計(jì)數(shù)器和若干個(gè)數(shù)據(jù)項(xiàng)的格式。
public class ClassTest {
private int m;
private int inc() {
return m + 1;
}
}
下面我們會(huì)通過上面這段代碼來分析Class文件的內(nèi)容。
上面這張圖是經(jīng)過編譯后的Class文件中的內(nèi)容
Class文件開頭固定的4個(gè)字節(jié)為魔數(shù),唯一作用就是用來確定這個(gè)文件是否是一個(gè)能被虛擬機(jī)接收的class文件。Java的魔數(shù)固定為0xCAFEBABE,接下去的兩個(gè)字節(jié)代表次要版本號(hào),再下去的兩個(gè)字節(jié)是主版本號(hào),主版本號(hào)為0x0034(十進(jìn)制是52,也就是JDK1.8),高版本的JDK能夠運(yùn)行以前版本的Class文件,但是不能運(yùn)行以后版本的Class文件,通俗一點(diǎn)將就是向下兼容。
走過了魔數(shù)和版本,接下去是Class文件中最關(guān)鍵的部分常量池,常量池由一個(gè)計(jì)數(shù)池和具體的常量項(xiàng)來組成,在我們代碼中常量池?cái)?shù)量為0x0013(十進(jìn)制是19),關(guān)于常量池的計(jì)數(shù)池有一個(gè)比較特殊的地方就是他是從1開始計(jì)數(shù)的,也就是說如果我們計(jì)數(shù)池的值是19,實(shí)際上是只有18個(gè)常量項(xiàng)。
常量池中主要存放兩大類常量:
字面量主要指的是文本字符串、聲明為final的常量值等
符號(hào)引用主要包含三類常量:
Java代碼在編譯的時(shí)候不存在連接時(shí),也就是Class文件中不會(huì)保存各個(gè)方法、字段的最終內(nèi)存布局信息,這些字段、方法的符號(hào)引用如果在運(yùn)行期不進(jìn)行轉(zhuǎn)換則得不到真正的內(nèi)存入口地址,所以在虛擬機(jī)運(yùn)行時(shí),需要從常量池獲得對(duì)應(yīng)的符號(hào)引用,在類創(chuàng)建和運(yùn)行時(shí)解析翻譯到具體的內(nèi)存地址中。
目前常量池中主要有以下表項(xiàng):
這些表都會(huì)有一個(gè)固定的字段也就是開始的第一個(gè)字節(jié)都是一個(gè)標(biāo)志位代表相應(yīng)的類型,如上圖。
大家可以通過javap -verbose xxx.class列出文件字節(jié)碼的內(nèi)容
通過比較javap -verbose常量池的項(xiàng)的索引和我們class文件二進(jìn)制的表示可以發(fā)現(xiàn)是一一對(duì)應(yīng)的。
關(guān)于如何理解Java Class文件常量池就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。