field_info 数据结构伪代码
field_info{
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[ attributes_count ];
}
method_info 数据结构伪代码
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 | 表明该类由编译器根据情况生成的,源码里无法显示定义这样的类。 |
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 | 表明该类由编译器根据情况生成的,源码里无法显示定义这样的类。 |
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 函数 |
ACC_BRIDGE | 0x0040 | 桥接方法,由编译器根据情况生成。 |
ACC_VARARGS | 0x0080 | 可变参数个数的函数。 |
ACC_NATIVE | 0x0100 | native 函数 |
ACC_ABSTRACT | 0x0400 | 抽象函数 |
ACC_STRICT | 0x0800 | strictfp 类型(strict float point,精确浮点) |
ACC_SYNTHETIC | 0x1000 | 表明该成员由编译器根据情况生成的,源码里无法直接定义这样的成员。 也被称为合成函数,内部类访问外部类的私有成员时,在class文件中也会生成一个 ACC_SYNTHETIC 修饰的函数。 |
attribute_info
attribute_info 数据结构伪代码
attribute_info {
u2 attribute_name_index; // 属性名称,指向常量池中(constant_pool)Utf8常量项的索引。
u4 attribute_length; // 该属性具体内容的长度,下面info的数组长度。
u1 info[ attribute_length ]; // 属性具体内容。这里是泛指,不同的属性,这里不一样。
}
与常量池类型不一样的是,属性是由其名称来区别的,即 attribute_info 中的 attribute_name_index 所指向的 Utf8 字符串。
attribute_name_index 字符表
属性名称和作用
名称 | 说明 |
"ConstantValue" | 该属性只出现于 field_info 中。 用于描述一个常量成员域(long、float、double、int、short、char、byte、boolean、String等)的值。 |
"Code" | 该属性只出现于 method_info 中,用于描述一个函数(非 native 和 abstract 的函数)的内容。 源码中该函数内容编译后得到的虚拟机指令,try/catch 语句对应的异常处理表等。 |
"Exceptions" | 当一个函数抛出异常(Exception)或错误(Error)时,这个函数的 method_info 将保存此属性。 |
"SourceFile" | 包含一个指向 Utf8 常量项的索引,包含此 Class 对应的源码文件名。 |
"LocalVariableTable" | 包含在 "Code" 属性中的属性,用来描述一个函数的本地变量相关的信息。 比如变量名称,在源码中对应的行号。 |
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
指向内容为 "Code" 的 CONSTANT_Utf8_info 常量项。
attribute_length
表示接下来内容的长度。
max_stack
用于说明这个函数在执行过程中,需要最深多少栈空间(栈项)。
JVM执行一个指令的时候,该指令的操作数存储在一个名为“操作数栈(operand stack)”的地方。
每一个操作数占用一个或两个(long、double 类型操作数)栈项。
stack是一块只能进行先入后出的内容。
max_locals
表示该函数最多包括几个局部变量。
code_length
代表 code 数组的长度。
code
函数对应的指令内容,也就是函数的源码经过编译器转换后得到的 Java指令码 存储在 code数组 中。
exception_table_length
表示函数中,异常表的长度。
exception_table
异常表,一个函数可以包含多个 try/catch 语句,一个 try/catch 语句对应 exception_table 数组中的一项。
start_pc
描述 try/catch 语句从哪条指令开始。code[ code_length ] 数组中。
end_pc
表示这个 try 语句到哪条指令结束(不包括 catch)。
handler_pc
表示 catch 语句的内容从哪条指令开始。
catch_type
表示 catch 中截获的 Exception 或 Error 的名字,指向 CONSTANT_Utf8_info 常量项。
如果 catch_type 取值为0,则表示它是 final{ } 语句块。
LineNumberTable
用于调试,指明指令对应的源码行号。
主要靠其结构里面的 start_pc 和 line_number
LineNumberTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 line_number_table_length;
{
u2 start_pc; // 指向 Code_attribute 中 code 数组某处指令
u2 line_number; // 指明 start_pc 位于源码的哪一行。
} line_number_table[ line_number_table_length ];
}
LocalVariableTable
用于调试,调试时可以用于计算本地变量值。
LocalVariableTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 local_variable_table_length;
{
u2 start_pc; // 指向 Code_attribute 中 code 数组某处指令
u2 length; // 指令长度
u2 name_index; // 此局部变量的名称,指向 CONSTANT_Utf8_info 常量项。
u2 descriptor_index; // 此局部变量的类型,指向 CONSTANT_Utf8_info 常量项。内容为 Field Descriptor 字符串描述符。
u2 index;
} local_variable_table[ local_variable_table_length ];
}