ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
cp_info {
u1 tag;
u1 info[];
}
CONSTANT_Utf8_info u1+u2+u1*length 0x01
CONSTANT_Integer_info u1+u4 0x03
CONSTANT_float_info u1+u4 0x04
CONSTANT_Long_info u1+u8 0x05
CONSTANT_Double_info u1+u8 0x06
CONSTANT_class_info u1+u2 0x07
CONSTANT_String_info u1+u2 0x08
CONSTANT_Fieldref_info u1+u2+u2 0x09
CONSTANT_Methodref_info u1+u2+u2 0x0a
CONSTANT_Interface_Methodref_info u5 0x0b
CONSTANT_NameAndType_info u5 0x0c
tag u1:12
name_index u2 指向该字段或方法名称的CONSTANT_Utf8_info索引
Class文件中变量,方法的名字以非限定名的形式保存的,简单讲就是单纯的变量名或方法名,是不能包含./[;等ASCII字符的。但有个例外
descriptor_index u2 指向CONSTANT_Utf8_info结构,代表一个验证的字段描述符或方法描述符
CONSTANT_MethodHandle_info u5 0x0f
tag u1 :15
reference_kind u2 决定方法类型,值必须是0- 9,该值表示方法句柄的字节码行为
reference_index u2 值必须是常量池的有效索引
1.reference_kind=1||2||3||4,指向CONSTANT_Fieldref_info索引
2.reference_kind=5||8,指向CONSTANT_Methodref_info索引
3.reference_kind=6||7
4.reference_kind=9,指向CONSTANT_InterfaceMethodref_info索引
5.reference_kind=8,指向CONSTANT_Methodref_info结构必须是方法
CONSTANT_MethodType_info u3 0x10
CONSTANT_InvokeDynamic_info u5 0x12
access_flags u2:字段访问标志
name_index u2: 字段名称索引,指向CONSTANT_Utf8_info索引
descriptor_index u2:描述符索引,指向CONSTANT_Utf8_info索引
字段描述符如何表示
attributes_count u2:属性个数
attributes[attributes_count]attribute_info->ConstantValue_attribute 字段表集合
access_flags u2:字段访问标志
name_index u2:方法名称索引,指向CONSTANT_Utf8_info索引的 or or 有效的非限定名称
descriptor_index u2 方法描述索引(返回参数索引),指向CONSTANT_Utf8_info索引
attributes_count u2 方法中属性个数
attributes attribute_info []
Code 执行方法 code_attribute_info
attribute_name_index u2 属性名索引,指向CONSTANT_Utf8_info中的“Code”
attribute_length u4 属性字节长度,不包括前6字节
max_stack u2 操作数栈的最大深度
max_locals u2 局部变量的最大数目,包含传入参数的局部变量
code_length u4 指令长度,表示代码数组中的字节数,必须大于0 小于65536
code[code_length] u1*code_length 指令集合
exception_table_length 异常计数 u1
exception_table[exception_table_length] 异常集合 u8*exception_table_length
attributes_count u2 Code结构内属性数
attributes attronites_info Code结构体内属性集合
LinaNumberTable 源码与指令关系 LinaNumberTable_info
attribute_name_index u2 属性名称,指向CONSTANT_Utf8_info中的“ LineNumberTable”
attribute_length u4 属性长度,需要去掉初始的6字节
line_number_table_length u2 源码指令关系表计数,表示LinaNumberTable的个数
line_number_table[line_number_table_ length] u4*line_number_table_length 源码指令关系表数组
LocalVariableTable 局部变量描述
attribute_name_index u2 属性名称,指向CONSTANT_Utf8_info中的“ LocalVariableTable”
attribute_length u4 属性长度,需要去掉初始的6字节
local_variable_table_length u2 局部变量描述计数,表示LocalVariableTable的个数
local_variable_table[local_variable_table_ length] u10*local_variable_table_length 局部变量描述表集合 local_variable_ info
LocalVariableTypeTable 局部变量类型表,方法中使用了泛型变量,则会生成局部变量类型表,对泛型类型的局部变量,需要在LocalVariableTable Attribute和LocalVariableTypeTable Attribute中同时存在一项;而对非泛型类型的局部变量来说,只要在LocalVariableTable Attribute存在表项就可以
如果方法中使用了泛型变量,则会生成 局部变量类型表;局部变量类型表的信息会覆盖掉 局部变量表的信息;JDK5之后才出现的 局部变量类型表,因为JDK5之前不支持泛型,为了兼容以前的老版本,不得不做了这个糟糕的设计;局部变量类型表在Hotspot中基本没有任何作用,仅用于作为Hotspot中的 局部变量表的 signature_cp_index字段赋值。
attribute_name_index u2 属性名称,指向CONSTANT_Utf8_info中的“ LocalVariableTypeTable”
attribute_length u4 属性长度,需要去掉初始的6字节
local_variable_type_table_length u2 表示LocalVariableTypeTable的个数
local_variable_type_table[local_variable_type_table_length]
StackMapTable stack_map_frame 栈图,为了提高JVM在类型检查的验证过程的效率,只用于Class文件加载时的校验
attribute_name_index u2 属性名称,指向CONSTANT_Utf8_info中的“ StackMapTable”
attribute_length u4 属性长度,需要去掉初始的6字节
number_of_entries u2 表示entries表的成员数量
entries[number_of_entries] stack_map_frame
frame_type
same_frame
frame_type = SAME ;/ 0-63 /
same_locals_1_stack_item_frame
frame_type = SAME_LOCALS_1_STACK_ITEM; / 64-127 /
verification_type_info stack[1];
same_locals_1_stack_item_frame_extended
frame_type u1= SAME_LOCALS_1_STACK_ITEM_EXTENDED;/* 64-127 */
offset_delta u2
verification_type_info stack[1]
chop_frame
frame_type = CHOP/ 248- 250 /
offset_delta u2
same_frame_extended
frame_type = SAME_FRAME_EXTENDED / 251/
offset_delta u2
append_frame
frame_type = APPEND ; / 252-254 /
offset_delta u2
verification_type_info locals[frame_type - 251]
full_frame
frame_type = FULL_FRAME;/ 255 /
offset_delta
number_of_locals
verification_type_info locals[number_of_locals]
u2 number_of_stack_items
verification_type_info stack[number_of_stack_items];
Exceptions 抛出异常的方法 Exception_ attribute_info
attribute_name_index u2 属性名称,指向名称为Exceptions 的常量池
attribute_length u4 属性长度
Number_of_exceptions u2 异常数量计数 ,表示有多少个异常名称索引
exceptions_index_table[Number_of_ exceptions] u2*Number_of_ exceptions 异常常量池索引
RuntimeVisibleParameterAnnotations 该方法在运行时可见的修饰该方法参数的Annotation,Java程序可以通过反射机制获取这些Annotation中的值
attribute_name_index u2 属性名称,指向名称为RuntimeVisibleParameterAnnotations 的常量池
attribute_length u4 属性长度
num_parameters u1 记录该方法中的参数个数
parameter_annotations[num_parameters] annotation
type_index u2 指向CONSTANT_Utf8_info描述符
num_element_value_pairs
element_value_pairs[num_element_value_pairs] element_value_pairs
RuntimeInvisibleParameterAnnotations 记录该方法在运行时不可见的修饰该方法参数的Annotation 结构与(RuntimeVisibleParameterAnnotations)相同
AnnotationDefault
MethodParameters
attribute_name_index u2 指向名称为“MethodParameters”的常量池
attribute_length u4 属性长度
parameters_count u1 参数的数量
parameters[parameters_count] parameter
SourceFile 记录源文件名称
InnerClasses 内部类列表
EnclosingMethod 仅当一个类为局部类或者匿名类是才能拥有这个属性
SourceDebugExtension
BootstrapMethods 这个属性用于保存 invokedynamic 指令引用的引导方法限定符
attribute_name_index u2 属性名称索引,指向值为“ BootstrapMethods”的常量池
attribute_length u4 表示属性的长度,不包括前六个字节。
num_bootstrap_methods u2 数组中的引导方法限定符的数量
bootstrap_methods[num_bootstrap_methods]
bootstrap_method_ref u2
num_bootstrap_arguments u2
bootstrap_arguments[num_bootstrap_arguments] u2*num_bootstrap_arguments
常量池在该索引处必须是下列结构之一:CONSTANT_String_info、CONSTANT_Class_info、CONSTANT_Integer_info、CONSTANT_Long_info、CONSTANT_Float_info、CONSTANT_Double_info、CONSTANT_MethodHandle_info 或 CONSTANT_MethodType_info
方法描述符(IDLjava/lang/Thread;)Ljava/lang/Object;
XMind: ZEN - Trial Version
关注公众号,每周都有新内容
获取脑图请回复公众号“class文件解析”获取PDF版本脑图,需要补充的知识点可以进行留言,逐步进行完善。
最后感谢大家的关注