格式不好控制,大家在閱讀時注意縮進。
magic[4字節] 魔數,用來判斷是否可以被虛擬機使用。固定值爲0xCAFEBABE(咖啡寶貝)
minor_version[2字節] 次版本號
major_version[2字節] 主版本號,低版本的jdk無法執行高版本的class文件。
constant_pool_count[2字節] 常量池裏的項目個數
constant_pool 常量池裏每一個項目類型都用一個tag標示。從1開始取值,比如取值爲1時,表示info裏存放的是utf8的字符串
tag[1字節] 不同的取值,決定了其下info的結構不同
info
access_flags[2字節] 類的訪問標識位,用來標識類是否具有pulbic/abstract/interface/final等修飾符。用其中的bit位標識是否存在。例如,如果是public的class,其值爲0x0001
this_class[2字節] 兩個字節的數值,指向常量池裏的某一個項目。這裏指向的是當前類的全名稱
super_class[2字節] 指向常量池裏的當前類的父類全名稱
interfaces_count[2字節] 當前類實現的接口個數
interfaces 每一個指向常量池裏的接口的全名稱
fields_count[2字節] 當前類的成員變量個數
fields 成員變量信息
access_flags[2字節] 成員變量的訪問標識,與上邊access_flags相似
name_index[2字節] 指向常量池裏當前字段的名字
desc_index[2字節] 指向常量池裏當前字段的描述。例如字符串類型對應的描述是'Ljava.lang.String;'
attribute_count[4字節] 字段的屬性表個數,跟類的屬性表類似。在下面介紹
attributes 存放字段的屬性信息
methods_count[2字節] 當前類的成員方法個數
mehtods 成員方法信息
access_flags[2字節] 成員方法的訪問標識,與上邊access_flags相似
name_index[2字節] 指向常量池裏當前方法的名字
desc_index[2字節] 指向常量池裏當前方法的簽名。比如 public String test(Object o) 方法對應描述是(Ljava.lang.Object;)Ljava.lang.String;
attributes_count[4字節] 方法的屬性表個數,跟類的屬性表類似。在下面介紹
attributes 存放方法的屬性信息,最重要的屬性就是Code,存放了方法的字節碼指令
attributes_count[2字節] 類的屬性表個數
attributes 類的屬性信息
attribute_name_index[2字節] 指向常量池裏屬性的名稱
attribute_length[4字節] 下邊info內容的長度
info 屬性的內容。不同的屬性,內容結構不同
以Code屬性表爲例,其結構如下:
attribute_name_index[2字節] 指向常量池裏的Code字符串
attribute_length[4字節] 該屬性的長度
max_stack[2字節] 當前方法操作數棧的最大深度
max_locals[2字節] 存放局部變量所需要的空間個數
code_length[4字節] 源碼編譯後字節碼指令的長度
code 字節碼指令
exception_table_length 異常表個數
exception_table 異常表
attributes_count 當前屬性下的屬性個數
attributes
從上邊的結構我們不難看出,其實Java class文件的各是還是比較簡潔的。其中的attributes可以根據需要隨時添加,用來滿足Jvm後期發展的需求。