一、描述
Class文件是一組以8位(1字節)為基礎單位的二進制流。
當數據項大於8位時,按照【高位在前】分割成若干個8位進行存儲。
按照Java虛擬機規范的規定,Class文件結構只有兩種數據類型:無符號數和表
二、無符號數
無符號數屬於基本的數據類型,以u1、u2、u4、u8來分別代表1字節,2字節,4字節,8字節的無符號數。
無符號數可用來描述數字、索引引用、數量值或者按照UTF-8編碼構成字符串值。
三、表
類型 | 名字 | 名稱 | 數量 | 描述 |
u4 | magic | 魔數 | 1 | Class文件1-4字節,是否能被JVM接受,更加安全 |
u2 | minor_version | 次版本號 | 1 | Class文件5-6字節 |
u2 | major_version | 主版本號 | 1 | Class文件7-8字節(52對應JDK1.8) |
u2 | constant_pool_count | 常量池大小 | 1 | 從1開始,第0項常量為空:不引用任何一個常量池項目 |
cp_info | constant_pool | 常量池 | constant_pool_count - 1 | 字面量:字符串、常量值等 符號引用:類和接口的全限定名;字段名稱和描述符;方法名稱和描述符 |
u2 | access_flag | 類訪問標志 | 1 | ACC_PUBLIC |
u2 | this_class | 類索引 | 1 | 確定類的全限定名 |
u2 | super_class | 父類索引 | 1 | 確定類的父類的全限定名(除Object,所有類的父類索引不為0) |
u2 | interfaces_count | 接口數量 | 1 | 確定接口數量 |
u2 | interfaces | 接口索引集合 | interfaces_count | 確定類實現了那些接口;如果數量為0,則不占用任何字節 |
u2 | fields_count | 字段數量 | 1 | 確定字段數量 |
field_info | fields | 字段集合 | fields_count | 描述接口或類中聲明的表量;類變量、實例表量 |
u2 | methods_count | 方法數量 | 1 | 確定方法數量 |
method_info | methods | 方法集合 | methods_count | 描述接口或者類中方法 |
u2 | attributes_count | 屬性數量 | 1 | 確定屬性數量 |
attribute_info | attributes | 屬性集合 | attributes_count | 描述屬性 |
3.1 常量池項目
常量 | 項目 | 類型 | 描述 |
CONSTANT_Utf8_info | tag | u1 | 1 |
length | u2 | 字符串字節數(UTF-8編碼) | |
bytes | u1 | 字符串(UTF-8編碼) | |
CONSTANT_Integer_info | tag | u1 | 3 |
bytes | u4 | int(高位在前) | |
CONSTANT_Float_info | tag | u1 | 4 |
bytes | u4 | float(高位在前) | |
CONSTANT_Long_info | tag | u1 | 5 |
bytes | u8 | long(高位在前) | |
CONSTANT_Double_info | tag | u1 | 6 |
bytes | u8 | double(高位在前) | |
CONSTANT_Class_info | tag | u1 | 7 |
index | u2 | 指向全限定名常量項的索引(CONSTANT_Utf8_info) | |
CONSTANT_String_info | tag | u1 | 8 |
index | u2 | 指向字符串字面量的索引(CONSTANT_Utf8_info) | |
CONSTANT_Fieldref_info | tag | u1 | 9 |
index | u2 | 指向聲明字段的類或接口描述符的索引(CONSTANT_Class_info) | |
index | u2 | 指向字段描述符的索引(CONSTATN_NameAndType_info) | |
CONSTANT_Methodref_info | tag | u1 | 10 |
index | u2 | 指向聲明方法的類描述符的索引(CONSTANT_Class_info) | |
index | u2 | 指向方法的名稱及類型描述符的索引(CONSTANT_NameAndType_info) | |
CONSTANT_InterfaceMethodref_info | tag | u1 | 11 |
index | u2 | 指向聲明方法的接口描述符的索引(CONSTANT_Class_info) | |
index | u2 | 指向方法的名稱及類型描述符的索引(CONSTANT_NameAndType_info) | |
CONSTANT_NameAndType_info | tag | u1 | 12 |
index | u2 | 指向字段或方法名稱常量項的索引(CONSTANT_Utf8_info) | |
index | u2 | 指向字段或方法描述符常量項的索引(CONSTANT_Utf8_info) | |
CONTANT_MethodHandle_info | tag | u1 | 15 |
reference_kind | u1 | 1-9;決定方法句柄類型;標識方法句柄的字節碼行為 | |
reference_index | u2 | 對常量池的有效索引 | |
CONSTANT_MethodType_info | tag | u1 | 16 |
descriptor_index | u2 | 對常量池的有效索引,方法的描述符(CONSTANT_Utf8_info) | |
CONSTANT_InvokeDynamic_info | tag | u1 | 18 |
bootstrap_method _attr_index |
u2 | 對當前Class文件中引導方法的bootstrap_methods[]數組的索引 | |
name_and_type_ index |
u2 | 對當前常量池的有效索引,方法名稱和方法描述符 (CONSTANT_NameAndType_info) |
3.2 描述符標識字段含義
標識字符 | 含義 |
B | 基本數據類型(byte) |
C | 基本數據類型(char) |
D | 基本數據類型(double) |
F | 基本數據類型(float) |
I | 基本數據類型(int) |
J | 基本數據類型(long) |
S | 基本數據類型(short) |
Z | 基本數據類型(boolean) |
V | 特殊類型(void) |
L | 對象類型(Ljava/lang/Object)([[Ljava/lang/Object) |
3.3類訪問標志
標志名稱 | 標志值 | 含義 |
ACC_PUBLIC | 0x0001 | 是否是public類型 |
ACC_FINAL | 0x0010 | 是否是final類型(類) |
ACC_SUPER | 0x0020 | 是否允許使用invokespecial字節碼指令的新語意 (JDK 1.0.2之后編譯出來的類為真) |
ACC_INTERFACE | 0x0200 | 標識接口 |
ACC_ABSTRACT | 0x0400 | 是否是abstract類型(接口和抽象類為真) |
ACC_SYNTHETIC | 0x1000 | 標識類不由用戶生成 |
ACC_ANNOTATION | 0x2000 | 標識注解 |
ACC_ENUM | 0x4000 | 標識枚舉 |
3.4.1 字段表集合
類型 | 名稱 | 數量 | 備注 |
u2 | access_flags | 1 | 字段訪問標志 |
u2 | name_index | 1 | 字段簡單名稱(CONSTANT_Utf8_info) |
u2 | descriptor_index | 1 | 字段的描述符(CONSTANT_Utf8_info) |
u2 | attributes_count | 1 | 屬性數量 |
attribute_info | attributes | attributes_count | 字段訪問標志的集合 |
3.4.2 字段訪問標志
標志名稱 | 標志值 | 含義 |
ACC_PUBLIC | 0x0001 | 字段是否public |
ACC_PRIVATE | 0x0002 | 字段是否private |
ACC_PROTECTED | 0x0004 | 字段是否protected |
ACC_STATIC | 0x0008 | 字段是否static |
ACC_FINAL | 0x0010 | 字段是否final |
ACC_VOLATILE | 0x0040 | 字段是否volatile |
ACC_TRANSIENT | 0x0080 | 字段是否transient |
ACC_SYNTHEIC | 0x1000 | 字段是否由編譯器自動產生 |
ACC_ENUM | 0x4000 | 字段是否enum |
3.5.1 方法表集合
類型 | 名稱 | 數量 | 備注 |
u2 | access_flags | 1 | 方法訪問標志(ACC_PUBLIC) |
u2 | name_index | 1 | 方法簡單名稱(CONSTANT_Utf8_info) |
u2 | desciptor_index | 1 | 方法的描述符(CONSTANT_Utf8_info) |
u2 | attributes_count | 1 | 屬性數量 |
attribute_info | attributes | attributes_count | 屬性集合 |
3.5.2 方法訪問標志
標志名稱 | 標志值 | 含義 |
ACC_PUBLIC | 0x0001 | 方法是否public |
ACC_PRIVATE | 0x0002 | 方法是否private |
ACC_PROTECTED | 0x0004 | 方法是否protected |
ACC_STATIC | 0x0008 | 方法是否static |
ACC_FINAL | 0x0010 | 方法是否final |
ACC_SYNCHRONIZED | 0x0020 | 方法是否synchronized |
ACC_BRIDGE | 0x0040 | 方法是否由編譯器產生的橋接方法 |
ACC_VARARGE | 0x0080 | 方法是否接受不定參數 |
ACC_NATIVE | 0x0100 | 方法是否native |
ACC_ABSTRACT | 0x0400 | 方法是否abstract |
ACC_STRICTFP | 0x0800 | 方法是否strictfp |
ACC_SYNTHETIC | 0x1000 | 方法是否由編譯器自動產生 |
3.6 屬性表
3.6.1 Code屬性
類型 | 名稱 | 數量 | 備注 |
u2 | attribute_name_index | 1 | 屬性名稱索引(CONSTANT_Utf8_info) |
u4 | attribute_length | 1 | 屬性長度 |
u2 | max_stack | 1 | |
u2 | max_locals | 1 | |
u4 | code_length | 1 | |
u1 | code | code_length | |
u2 | exception_table_length | 1 | |
exception_info | exception_table | exception_table_length | |
u2 | attributes_count | 1 | |
attribute_info | attributes | attributes_count |
3.6.2 Exception
類型 | 名稱 | 數量 | 備注 |
u2 | attribute_name_index | 1 | |
u4 | attribute_length | 1 | |
u2 | number_of_exceptions | 1 | 異常數量 |
u2 | exception_index_table | number_of_exception | 異常(CONSTANT_Class_info) |