1. 程式人生 > >【Java虛擬機器】類檔案結構

【Java虛擬機器】類檔案結構

類檔案結構

class檔案是一組8位位元組為基礎單位的二進位制流,各個資料專案嚴格按照順序緊湊地排列在class檔案中,中間沒有新增任何分隔符。遇到需要佔用8位位元組以上空間的資料項時,則會按照高位在前的方式分割成若干個8位位元組進行儲存。

class檔案格式只有兩種資料型別:無符號數和表(info字尾),每種表都有自己的資料結構。

無符號數屬於基本的資料型別,以u1、u2、u4、u8來分別代表1個位元組、2個位元組、4個位元組和8個位元組的無符號數,無符號數可以用來表述數字、索引引用、數量值或者按照utf-8編碼構成字串值。

類檔案由下列專案依次構成

型別 名稱 數量
u4 magic 魔數 1
u2 minor_version 次版本號 1
u2 major_version 主版本號 1
u2 constant_pool_count 常量數量 1
cp_info constant_pool 常量池 constant_pool_count
u2 access_flags 訪問標誌 1
u2 this_class 類索引 1
u2 super_class 父類索引 1
u2 interface_count 介面索引集合數量 1
u2 interfaces 介面索引集合 interface_count
u2 fields_count 欄位表數量 1
field_info fields 欄位表 fields_count
u2 methods_count 方法表數量 1
method_info methods 方法表 methods_count
u2 attribute_count 屬性表數量 1
attribute_info attributes 屬性表 attribute_count

關於各項內容

魔數

每個class檔案的頭四個檔案稱為魔數,唯一作用就是確定這個檔案是否為一個能被虛擬機器接受的class檔案。和字尾的性質是一樣的,只是字尾容易被人修改掉。

class檔案的魔數為:0xCAFEBABE(咖啡寶貝?)

版本號

高版本的JDK能向下相容以前版本的class檔案,但不能執行以後版本的class檔案,即使檔案格式並未發生任何變化。

常量池

常量池的數量是從1開始的,比如說常量池數量為22,則代表常量池中有21項常量,索引範圍為1~21。

常量池中存放兩大類常量:字面量和符號引用。字面量就是文字字串、常量值等;符號引用包括類和介面的全限定名、欄位的名稱和描述符、方法的名稱和描述符。

訪問標誌

訪問標誌用於識別一些類或者介面層次的訪問資訊,包括:這個class是類還是介面;是否定義位publi型別;是否定義位abstract型別等。

類索引、父類索引與介面索引集合

  • 類索引確定這個類的全限定名
  • 父類索引確定這個類的父類的許可權定名
  • 介面索引集合確定它實現所有介面的全限定名的集合,順序是按照implements後的介面順序從左到右

欄位表集合

欄位表用於描述介面或者類中宣告的變數。欄位包括類級變數以及例項變數。可以包括的資訊有:欄位的作用域(public、private、protected)、可變性(final)、併發可見性(volatile)、可否被序列化(transient)、欄位基本型別(基本型、物件、陣列)、欄位名稱等。

方法表集合

包括訪問標誌、方法名稱、方法引數、方法返回型別等。

屬性表

在class檔案、欄位表、方法表都可以攜帶自己的屬性表集合,以用於描述某些場景專有的資訊。

比如說class檔案中的InnerClasses屬性用來描述內部類列表
比如說欄位表中的ConstantValue屬性用於存放static final修飾的欄位
比如說方法表中的Code用於屬性用來儲存位元組碼指令

參考

  1. 深入理解Java虛擬機器[書籍]