Java虛擬機(二)—class結構

類文件結構

類文件是一組以8位字節為基礎的二進制流,各個數據必須嚴格按照順序排列在類文件中,并且只有兩種數據類型

  • 無符號數: 描述數字、索引引用、數量值或者UTF-8編碼的字符串
  • 表: 由無符號數或其它表作為數據結構的符合數據類型
名稱 類型 數量
magic u4 1
minor_version u2 1
major_version u2 1
constant_pool_count u2 1
constant_pool cp_info constant_pool_count-1
access_flag u2 1
this_class u2 1
super_class u2 1
interfaces_count u2 1
interfaces u2 1
fields_count u2 1
field_info fields fields_count
methods_count u2 1
methods methods_info methods_count
atrributes_count u2 1
atrributes atrribute_info atrributes_count

魔數和class文件版本

每個class文件頭4個字節稱為魔數(magic),用于確定這個class文件是否能被虛擬機接受,class文件魔數為0xCAFEBABE。

緊接著魔數后4個字節是class文件版本號,第5和第6字節是次版本號(minor_version),第7和第8字節是主版本號(major_version)

常量池

主版本號之后是常量池入口,常量池是class文件結構中與與其它數據關聯最多的數據類型。常量池入口有一個u2類型的數據,代表常量池容量計數(constant_pool_count),這個值從1開始,0有特殊作用,表示在特定情況下不引用任何一個常量池項目。

常量池中主要存放一下兩種常量

  • 字面量(Literal): 常量,如文本字符串和被聲明為final的常量值等
  • 符號引用(Symbolic Reference):
    • 類和接口的全限定名
    • 字段的名稱和描述符
    • 方法的名稱和描述符

訪問標記

常量池之后是訪問標記(access_flag),用于識別一些類或接口的訪問信息

標記名稱 標記值 含義
ACC_PUBLIC 0x0001 是否為public
ACC_FINAL 0x0010 是否為final,只有類可以設置
ACC_SUPER 0x0020 是否允許使用invokespecial字節碼指令,JDK 1.2之后為true
ACC_INTERFACE 0x0200 是否為接口
ACC_ABSTRACT 0x0400 是否為abstract類型,接口和抽象類為true,其它為false
ACC_SYNTHETIC 0x1000 非用戶代碼產生
ACC_ANNOTATION 0x2000 是否為注解
ACC_ENUM 0x4000 是否為枚舉

類索引、父類索引和接口索引集合

  • 類索引(this_class): 用于確定這個類的全限定名
  • 父類索引(super_class)是u2類型: 用于確定這個父類的全限定名
  • 接口索引(interfaces_count): 用來描述這個類實現了哪些接口,是一組u2類型的數據集合

字段表集合

  • 字段表(field_info): 用于描述接口或類中聲明的變量
  • 字段(fields): 包含了類級別變量或實例變量,但不包含方法內部聲明的變量

字段表結構

名稱 類型 數量 說明
access_flags u2 1 訪問限定標記
name_index u2 1 對常量池引用,字段的簡單名字
descriptor_index u2 1 對常量池引用,字段和方法的描述符
attributes_count u2 1
attributes attributes_info 1

字段訪問標志

|ACC_PUBLIC| 0x0001 | 是否為public|
|ACC_PRIVATE| 0x0002 | 是否為private|
|ACC_PROTECTED| 0x0004 | 是否為protected|
|ACC_STATIC| 0x0008| 是否為static|
|ACC_FINAL| 0x0010| 是否為final|
|ACC_VOLATILE| 0x0040| 是否為volitale|
|ACC_TRANSIENT| 0x0080| 是否為transient|
|ACC_SYNTHETIC| 0x1000| 是否由編譯器自動產生|
|ACC_ENUM| 0x4000| 是否為枚舉|

方法表集合

和字段表集合類似

屬性表集合

屬性表(attributes_info)用于描述某些場景專有的信息。

名稱 使用位置 含義
Code 方法表 Java代碼變異成的字節碼指令
ConstantValue 字段表 final關鍵定義的常量
Deprecated 類、方法和字段表 被聲明為deprecated的方法和字段
Execeptions 方法表 方法跑出的異常
InnerClass 類方法 內部類列表
LineNumberTable Code屬性 Java源碼的行號與字節指令的對應關系
LocalVariableTable Code屬性 方法的局部變量描述
SourceFile 類文件 源文件名稱
Synthetic 類、方法和字段表 表示方法或字段為編譯器自動生成
code屬性

Java方法體里的代碼被編譯器處理后最終變成字節碼存在code屬性內

名稱 類型 數量 說明
attribute_name_index u2 1 指向CONSTANT_Utf8_info常量的索引,固定為Code
attribute_length u4 1 屬性值的長度
max_stack u2 1 操作棧最大深度,虛擬機運行時需要根據這個值來分配棧幀的棧深度
max_locals u2 1 表示局部變量所需的儲存空間,單位是slot,是虛擬機為局部變量分配內存所使用的最小單位(1 slot = 32bit)
code_length u4 1 字節碼的長度,雖然是u4,但是字節碼長度不能超過65535
code u1 code_length 儲存字節碼
exception_table_length u2 1
exception_table exception_info 1
attribues_count u2 1
attributes attribute_info attribues_count

Exception屬性

用于列舉出方法中可能拋出的受查異常

名稱 類型 數量 說明
attribute_name_index u2 1
attribute_length u4 1 屬性值的長度
number_of_exceptions u2 1
exception_index_table u2 number_of_exceptions

LineNumberTable屬性

用于描述Java源代碼和字節碼行號(偏移量)之間的對應關系,不是運行時必須的屬性,如果不生成該屬性就無法再拋出異常時返回代碼中對應的行號。

名稱 類型 數量 說明
attribute_name_index u2 1 屬性值的索引
attribute_length u4 1 屬性值的長度
line_number_table_Length u2 1
line_number_table line_number_info line_number_table_length

LocalVariableTable屬性

用于描述棧幀中局部變量表中的變量與Java源碼中定義的變量之間的關系,不是運行時必須的屬性,如果沒有生成所有參數名稱都將丟失

名稱 類型 數量 說明
attribute_name_index u2 1 屬性值的索引
attribute_length u4 1 屬性值的長度
local_variable_table_Length u2 1
local_variable_table local\ _variable_info local_variable_table_length
local_variable_info結構
名稱 類型 數量 說明
start_pc u2 1 這個局部變量聲明周期開始時的字節碼偏移量
length u2 1 這個局部變量聲明周期開始時的字節碼作用范圍的長度
name_index u2 1 指向CONSTANT_Utf8_info常量的索引,代表局部變量的名稱
descriptor_index 1 指向CONSTANT_Utf8_info常量的索引,代表局部變量的描述符
index 1 u2 表示這個局部變量在棧幀局部變量中slot的位置

SourceFile屬性

用于記錄生成這個class文件源代碼的名稱,是可選的,如果不生成這個屬性,拋出異常時不會顯示出錯代碼的文件名。

名稱 類型 數量 說明
attribute_name_index u2 1 屬性值的索引
attribute_length u4 1 屬性值的長度
sourcefule_index u2 1 指向CONSTANT_Utf8_info常量的索引,常量值時源碼文件的文件名

ConstantValue屬性

ConstantValue屬性的作用是通知虛擬機自動為靜態變量賦值,只有被static修飾的變量才能用這個屬性

名稱 類型 數量 說明
attribute_name_index u2 1 屬性值的索引
attribute_length u4 1 屬性值的長度
constant_value_index u2 1 指向常量池的引用

InnerClasses屬性

InnerClasses屬性用于記錄內部類與宿主類之間的關聯,如果一個類中有內部類,則會生成InnerClass屬性。

名稱 類型 數量 說明
attribute_name_index u2 1 屬性值的索引
attribute_length u4 1 屬性值的長度
nubmber_of_classes u2 1 代表記錄多少個內部類信息
inner_class inner_class_info nubmber_of_classes
inner_class_info
名稱 類型 數量 說明
inner_class_info_index u2 1 指向CONSTANT_Class_info常量的索引,代表內部類的符號引用
outter_class_info_index u2 1 指向CONSTANT_Class_info常量的索引,代表宿主類的符號引用
inner_name_index u2 1 指向CONSTANT_Utf8_info常量的索引,代表這個內部類的名稱,如果是匿名內部類則為0
inner_name_access_flag u2 1 內部類的訪問標志

Deprecated屬性

表示某個類、字段或方法不再推薦使用

Synthetic屬性

表示該字段和方法是不是有Java源碼直接生成的

名稱 類型 數量 說明
attribute_name_index u2 1 屬性值的索引
attribute_length u4 1 屬性值的長度,值必須為0x00000000

參考

  • 深入理解Java虛擬機, 周志明
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內容