field_info 數(shù)據(jù)結(jié)構(gòu)偽代碼
field_info{
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[ attributes_count ];
}
method_info 數(shù)據(jù)結(jié)構(gòu)偽代碼
method_info{
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[ attributes_count ];
}
Class 的 access_flags
| 標志名稱 | 取值 | 說明 |
| ACC_PUBLIC | 0x0001 | public 類型 |
| ACC_FINAL | 0x0010 | final 類型 |
| ACC_SUPER | 0x0020 | 用于 invokespecial 指令 |
| ACC_INTERFACE | 0x0200 | 表明這個類是一個 Interface |
| ACC_ABSTRACT | 0x0400 | abstract 類型 |
| ACC_SYNTHETIC | 0x1000 | 表明該類由編譯器根據(jù)情況生成的,源碼里無法顯示定義這樣的類。 |
| ACC_ANNOTATION | 0x2000 | 注解類型 |
| ACC_ENUM | 0x4000 | 枚舉類型 |
Field 的 access_flags
| 標志名稱 | 取值 | 說明 |
| 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_SYNTHETIC | 0x1000 | 表明該類由編譯器根據(jù)情況生成的,源碼里無法顯示定義這樣的類。 |
| ACC_ENUM | 0x4000 | 枚舉類型 |
Method 的 access_flags
| 標志名稱 | 取值 | 說明 |
| ACC_PUBLIC | 0x0001 | public 類型 |
| ACC_PRIVATE | 0x0002 | private 類型 |
| ACC_PROTECTED | 0x0004 | protected 類型 |
| ACC_STATIC | 0x0008 | static 類型 |
| ACC_FINAL | 0x0010 | final 類型 |
| ACC_SYNCHRONIZED | 0x0020 | synchronized 函數(shù) |
| ACC_BRIDGE | 0x0040 | 橋接方法,由編譯器根據(jù)情況生成。 |
| ACC_VARARGS | 0x0080 | 可變參數(shù)個數(shù)的函數(shù)。 |
| ACC_NATIVE | 0x0100 | native 函數(shù) |
| ACC_ABSTRACT | 0x0400 | 抽象函數(shù) |
| ACC_STRICT | 0x0800 | strictfp 類型(strict float point,精確浮點) |
| ACC_SYNTHETIC | 0x1000 | 表明該成員由編譯器根據(jù)情況生成的,源碼里無法直接定義這樣的成員。 也被稱為合成函數(shù),內(nèi)部類訪問外部類的私有成員時,在class文件中也會生成一個 ACC_SYNTHETIC 修飾的函數(shù)。 |
attribute_info
attribute_info 數(shù)據(jù)結(jié)構(gòu)偽代碼
attribute_info {
u2 attribute_name_index; // 屬性名稱,指向常量池中(constant_pool)Utf8常量項的索引。
u4 attribute_length; // 該屬性具體內(nèi)容的長度,下面info的數(shù)組長度。
u1 info[ attribute_length ]; // 屬性具體內(nèi)容。這里是泛指,不同的屬性,這里不一樣。
}
與常量池類型不一樣的是,屬性是由其名稱來區(qū)別的,即 attribute_info 中的 attribute_name_index 所指向的 Utf8 字符串。
attribute_name_index 字符表
屬性名稱和作用
| 名稱 | 說明 |
| "ConstantValue" | 該屬性只出現(xiàn)于 field_info 中。 用于描述一個常量成員域(long、float、double、int、short、char、byte、boolean、String等)的值。 |
| "Code" | 該屬性只出現(xiàn)于 method_info 中,用于描述一個函數(shù)(非 native 和 abstract 的函數(shù))的內(nèi)容。 源碼中該函數(shù)內(nèi)容編譯后得到的虛擬機指令,try/catch 語句對應(yīng)的異常處理表等。 |
| "Exceptions" | 當一個函數(shù)拋出異常(Exception)或錯誤(Error)時,這個函數(shù)的 method_info 將保存此屬性。 |
| "SourceFile" | 包含一個指向 Utf8 常量項的索引,包含此 Class 對應(yīng)的源碼文件名。 |
| "LocalVariableTable" | 包含在 "Code" 屬性中的屬性,用來描述一個函數(shù)的本地變量相關(guān)的信息。 比如變量名稱,在源碼中對應(yīng)的行號。 |
Code 屬性
Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[ code_length ];
u2 exception_table_length;
{
u2 start_pc; // pc (program counter)
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[ exception_table_length ];
u2 attributes_count;
attribute_info attributes[ attributes_count ];
......
}
attribute_name_index
指向內(nèi)容為 "Code" 的 CONSTANT_Utf8_info 常量項。
attribute_length
表示接下來內(nèi)容的長度。
max_stack
用于說明這個函數(shù)在執(zhí)行過程中,需要最深多少棧空間(棧項)。
JVM執(zhí)行一個指令的時候,該指令的操作數(shù)存儲在一個名為“操作數(shù)棧(operand stack)”的地方。
每一個操作數(shù)占用一個或兩個(long、double 類型操作數(shù))棧項。
stack是一塊只能進行先入后出的內(nèi)容。
max_locals
表示該函數(shù)最多包括幾個局部變量。
code_length
代表 code 數(shù)組的長度。
code
函數(shù)對應(yīng)的指令內(nèi)容,也就是函數(shù)的源碼經(jīng)過編譯器轉(zhuǎn)換后得到的 Java指令碼 存儲在 code數(shù)組 中。
exception_table_length
表示函數(shù)中,異常表的長度。
exception_table
異常表,一個函數(shù)可以包含多個 try/catch 語句,一個 try/catch 語句對應(yīng) exception_table 數(shù)組中的一項。
start_pc
描述 try/catch 語句從哪條指令開始。code[ code_length ] 數(shù)組中。
end_pc
表示這個 try 語句到哪條指令結(jié)束(不包括 catch)。
handler_pc
表示 catch 語句的內(nèi)容從哪條指令開始。
catch_type
表示 catch 中截獲的 Exception 或 Error 的名字,指向 CONSTANT_Utf8_info 常量項。
如果 catch_type 取值為0,則表示它是 final{ } 語句塊。
LineNumberTable
用于調(diào)試,指明指令對應(yīng)的源碼行號。
主要靠其結(jié)構(gòu)里面的 start_pc 和 line_number
LineNumberTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 line_number_table_length;
{
u2 start_pc; // 指向 Code_attribute 中 code 數(shù)組某處指令
u2 line_number; // 指明 start_pc 位于源碼的哪一行。
} line_number_table[ line_number_table_length ];
}
LocalVariableTable
用于調(diào)試,調(diào)試時可以用于計算本地變量值。
LocalVariableTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 local_variable_table_length;
{
u2 start_pc; // 指向 Code_attribute 中 code 數(shù)組某處指令
u2 length; // 指令長度
u2 name_index; // 此局部變量的名稱,指向 CONSTANT_Utf8_info 常量項。
u2 descriptor_index; // 此局部變量的類型,指向 CONSTANT_Utf8_info 常量項。內(nèi)容為 Field Descriptor 字符串描述符。
u2 index;
} local_variable_table[ local_variable_table_length ];
}