您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何理解Java Class文件常量池,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
Class文件的存在使得不同語言編寫的程序都可以運行在Java虛擬機上,只需要這些語言經過編譯器編譯后的Class文件符合Java虛擬機定義的規范,Java虛擬機就可以加載執行這些Class文件。如下圖所示:
Class文件是一組以8位字節為基礎單位的二進制流,各個數據項目嚴格按照順序緊湊地排列在Class文件中,當遇到需要占用8個字節以上空間的數據是,則按照大端序的方式分割成若干個8位字節進行存儲。
Class文件中只存在兩種數據類型:
無符號數屬于基本數據類型,以u1、u2、u4、u8分別表示1個、2個、4個和8個字節的無符號數,無符號數可以用來描述數字、索引引用、數量值或者按照UTF-8編碼構成的字符串值。
表是由無符號數和其他表組成的數據結構,所有的表都以_info結尾。
當在描述一個可變長度的類型數據時,通常會采用一個容量計數器和若干個數據項的格式。
public class ClassTest {
private int m;
private int inc() {
return m + 1;
}
}
下面我們會通過上面這段代碼來分析Class文件的內容。
上面這張圖是經過編譯后的Class文件中的內容
Class文件開頭固定的4個字節為魔數,唯一作用就是用來確定這個文件是否是一個能被虛擬機接收的class文件。Java的魔數固定為0xCAFEBABE,接下去的兩個字節代表次要版本號,再下去的兩個字節是主版本號,主版本號為0x0034(十進制是52,也就是JDK1.8),高版本的JDK能夠運行以前版本的Class文件,但是不能運行以后版本的Class文件,通俗一點將就是向下兼容。
走過了魔數和版本,接下去是Class文件中最關鍵的部分常量池,常量池由一個計數池和具體的常量項來組成,在我們代碼中常量池數量為0x0013(十進制是19),關于常量池的計數池有一個比較特殊的地方就是他是從1開始計數的,也就是說如果我們計數池的值是19,實際上是只有18個常量項。
常量池中主要存放兩大類常量:
字面量主要指的是文本字符串、聲明為final的常量值等
符號引用主要包含三類常量:
Java代碼在編譯的時候不存在連接時,也就是Class文件中不會保存各個方法、字段的最終內存布局信息,這些字段、方法的符號引用如果在運行期不進行轉換則得不到真正的內存入口地址,所以在虛擬機運行時,需要從常量池獲得對應的符號引用,在類創建和運行時解析翻譯到具體的內存地址中。
目前常量池中主要有以下表項:
這些表都會有一個固定的字段也就是開始的第一個字節都是一個標志位代表相應的類型,如上圖。
大家可以通過javap -verbose xxx.class列出文件字節碼的內容
通過比較javap -verbose常量池的項的索引和我們class文件二進制的表示可以發現是一一對應的。
關于如何理解Java Class文件常量池就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。