附加属性(Attributes)被用于ClassFile, field_info, method_info,Code_attribute结构中。
数据结构:
attribute_info {
u2 attribute_name_index; //unsigned 16-bit -> CONSTANT_Utf8_info
u4 attribute_length; //bytes
u1 info[attribute_length];
}
aadfadfadfadfadf
属性 | class版本 | Java SE版本 | 位置 | 类型 | 作用 | 说明 ---|---|---|---|--|---|---- ConstantValue | 45.3 | 1.0.2 | field_info | F | 用于常量初始化赋值,如没有常量字段则忽略 | 必有 Code | 45.3 | 1.0.2 | method_info | V | JVM指令,包括构造器 | 必有 StackMapTable | 50.0 | 6 | Code | V | 在运行时,提供类型检查(可直接通过table,而不需要类型推测) | 必有 Exceptions | 45.3 | 1.0.2 | method_info | V | 方法可能抛出的异常(checked) | 必有 InnerClasses | 45.3 | 1.0.2 | ClassFile | V | 内部类 | 可选,JavaSE EnclosingMethod | 49.0 | 5.0 | ClassFile | F | 仅当局部类、匿名内部类 | 可选,JavaSE Synthetic | 45.3 | 1.1 | ClassFile, field_info, method_info | F | 非源码/编译器产生(不包括实例初始化方法;类/接口初始化方法;Enum.values()
;Enum.valueOf()
)|可选,JavaSE Signature | 49.0 | 5.0 | ClassFile, field_info, method_info | F | 签名;主要用于反射/DEBUG/{B C D F I J S Z;V;...} | 可选,JavaSE SourceFile | 45.3 | 1.0.2 | ClassFile | F | 最多一个 | 可选,JavaSE SourceDebugExtension | 49.0 | 5.0 | ClassFile | V | 可选,最多一个;扩展的DEBUG信息 | 可选,元数据,JavaSE LineNumberTable | 45.3 | 1.0.2 | Code | V | code对应的源码行数 | 可选,JavaSE LocalVariableTable | 45.3 | 1.0.2 | Code | V | 在运行期方便的跟踪局部变量/参数(槽位Slot分布) | 可选,JavaSE LocalVariableTypeTable | 49.0 | 5.0 | Code | V | 在运行期方便的跟踪局部变量/参数 | 可选,JavaSE Deprecated | 45.3 | 1.1 | ClassFile, field_info, method_info | F | 标记性 | 可选,元数据,JavaSE RuntimeVisibleAnnotations | 49.0 | 5.0 | ClassFile,field_info,method_info | V | 声明注解运行时可见 | 可选,元数据,JavaSE RuntimeInvisibleAnnotations | 49.0 | 5.0 | ClassFile,field_info,method_info | V | 声明注解运行时不可见 | 可选,元数据,JavaSE RuntimeVisibleParameterAnnotations | 49.0 | 5.0 | method_info | V | 运行时,参数的注解可见 | 可选,元数据,JavaSE RuntimeInvisibleParameterAnnotations | 49.0 | 5.0 | method_info | V | 运行时,参数的注解不可见 | 可选,元数据,JavaSE RuntimeVisibleTypeAnnotations | 52.0 | 8 | ClassFile,field_info,method_info, Code | V | 用于声明式/表达式的运行时可见注解 | 可选,元数据,JavaSE RuntimeInvisibleTypeAnnotations | 52.0 | 8 | ClassFile,field_info,method_info, Code | V | 用于声明式/表达式的运行时不可见注解 | 可选,元数据,JavaSE AnnotationDefault | 49.0 | 5.0 | method_info | V | 注解默认值(default关键字) | 可选,元数据,JavaSE BootstrapMethods | 51.0 | 7 | ClassFile | V | 记录动态方法信息(被invokedynamic指令调用);需要与CONSTANT_InvokeDynamic_info对应 | 必有 MethodParameters | 52.0 | 8 | method_info | V | 用于记录表达式形式的方法参数 | 可选,元数据,JavaSE Module | 53.0 | 9 | ClassFile | V | 用于标记JAVA 9的模块 | 可选,元数据,JavaSE ModulePackages | 53.0 | 9 | ClassFile | V | 包括所有exported或opened的Module属性 | 可选,元数据,JavaSE ModuleMainClass | 53.0 | 9 | ClassFile | F | 指明Module的主类 | 可选,元数据,JavaSE
- ConstantValue
ConstantValue_attribute {
u2 attribute_name_index; //CONSTANT_Utf8_info
u4 attribute_length;
u2 constantvalue_index; //constant_pool中的一个值
}
Constant value attribute types:
Field Type | Entry Type |
---|---|
long | CONSTANT_Long |
float | CONSTANT_Float |
double | CONSTANT_Double |
int, short, char, byte, boolean | CONSTANT_Integer |
String | CONSTANT_String |
- Code
Code_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "Code"
u4 attribute_length; // excluding the initial six bytes
u2 max_stack;
u2 max_locals; // local variables/parameters/long or double is max_locals - 2
u4 code_length; // (0,65536)
u1 code[code_length]; // 读入内存后可按字节寻址(byte-addressable),
// 数组起始(第一个字节)位置按4字节对齐
//(tableswitch and lookupswitch 32-bit offsets will be 4-byte aligned)
u2 exception_table_length; // number of entries in the exception_table table
{
u2 start_pc; // ranges in the code array [start_pc, end_pc)
u2 end_pc; // ranges in the code array [start_pc, end_pc)
u2 handler_pc; //
u2 catch_type; // CONSTANT_Class_info -> constant_pool
// zero, => finally
} exception_table[exception_table_length];
u2 attributes_count; //
attribute_info attributes[attributes_count]; // optional
}
- StackMapTable
- 栈图,其方法的code属性中存储了局部变量和操作数的类型验证以及字节码的偏移量
- 必须准确知道每个字节码指令对应的局部变量和操作数栈的类型
- 因为Java7在编译的时期做了一些验证期间要做的事情,那就是类型检查,也就是栈图包含的内容
- 代码跳转,分支,goto时,对变量和指令进行校验
- 第一个隐式
StackMapTable_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "StackMapTable"
u4 attribute_length; // excluding the initial six bytes
u2 number_of_entries; // the number of stack_map_frame entries in the entries table
stack_map_frame entries[number_of_entries]; // stack map frame
}
union verification_type_info {
Top_variable_info;
Integer_variable_info;
Float_variable_info;
Long_variable_info;
Double_variable_info;
Null_variable_info;
UninitializedThis_variable_info;
Object_variable_info;
Uninitialized_variable_info;
}
Top_variable_info {
u1 tag = ITEM_Top; /* 0 */
}
Integer_variable_info {
u1 tag = ITEM_Integer; /* 1 */
}
Float_variable_info {
u1 tag = ITEM_Float; /* 2 */
}
Double_variable_info {
u1 tag = ITEM_Double; /* 3 */
}
Long_variable_info {
u1 tag = ITEM_Long; /* 4 */
}
Null_variable_info {
u1 tag = ITEM_Null; /* 5 */
}
UninitializedThis_variable_info {
u1 tag = ITEM_UninitializedThis; /* 6 */
}
Object_variable_info {
u1 tag = ITEM_Object; /* 7 */
u2 cpool_index;
}
Uninitialized_variable_info {
u1 tag = ITEM_Uninitialized; /* 8 */
u2 offset;
}
frame_type:
union stack_map_frame {
same_frame; // [0-63]
// 表示与前一个栈帧有着同样的局部变量,且前一个操作栈为空
// offset_delta = frame_type
same_locals_1_stack_item_frame; // [64, 127]
// 表示与前一个栈帧有着同样的局部变量,且前一个操作栈有一个实体
// offset_delta = frame_type - 64
same_locals_1_stack_item_frame_extended; // 247
// 表示与前一个栈帧有着同样的局部变量,且前一个操作栈有一个实体
// 与上一个不同的是,偏移量明确给出
chop_frame; // [248-250]
// 表示与前一个栈帧除了最后K个变量不同,其他局部变量不变,且操作栈为空
// K = 251 - frame_type
same_frame_extended; // 251
// 表示与前一个栈帧有着同样的局部变量,且操作栈为空
append_frame; // [252-254]
// 表示与前一个栈帧除了K个变量不同,其他局部变量不变,且操作栈为空
// K = frame_type - 251
full_frame; // 255
//
}
same_frame {
u1 frame_type = SAME; /* 0-63 */
}
same_locals_1_stack_item_frame {
u1 frame_type = SAME_LOCALS_1_STACK_ITEM; /* 64-127 */
verification_type_info stack[1];
}
same_locals_1_stack_item_frame_extended {
u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED; /* 247 */
u2 offset_delta;
verification_type_info stack[1];
}
chop_frame {
u1 frame_type = CHOP; /* 248-250 */
u2 offset_delta;
}
same_frame_extended {
u1 frame_type = SAME_FRAME_EXTENDED; /* 251 */
u2 offset_delta;
}
append_frame {
u1 frame_type = APPEND; /* 252-254 */
u2 offset_delta;
verification_type_info locals[frame_type - 251]; // locals[M+1] represents local variable N+1 / N+2(Long_variable_info or Double_variable_info)
}
full_frame {
u1 frame_type = FULL_FRAME; /* 255 */
u2 offset_delta;
u2 number_of_locals;
verification_type_info locals[number_of_locals]; // locals[M+1] represents local variable N+1 / N+2(Long_variable_info or Double_variable_info)
u2 number_of_stack_items;
verification_type_info stack[number_of_stack_items]; // stack[M+1] represents stack entry N+1 / N+2(Long_variable_info or Double_variable_info)
}
- Exceptions
Exceptions_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "Exceptions"
u4 attribute_length; // excluding the initial six bytes
u2 number_of_exceptions; // the number of entries in the exception_index_table
u2 exception_index_table[number_of_exceptions]; // CONSTANT_Class_info -> constant_pool
}
- InnerClasses
InnerClasses_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "InnerClasses"
u4 attribute_length; // excluding the initial six bytes
u2 number_of_classes; // the number of entries in the classes array
{
u2 inner_class_info_index; // CONSTANT_Class_info -> constant_pool
u2 outer_class_info_index; // zero => [anonymous class , local class ,top-level class or interface]
// CONSTANT_Class_info - constant_pool
u2 inner_name_index; // zero => anonymous class
// anonymous class -> constant_pool
u2 inner_class_access_flags; // Table 4.7.6-A. Nested class access and property flags
} classes[number_of_classes]; //
}
Flag Name | Flag Name | Interpretation |
---|---|---|
ACC_PUBLIC | 0x0001 | public |
ACC_PRIVATE | 0x0002 | private |
ACC_PROTECTED | 0x0004 | protected |
ACC_STATIC | 0x0008 | static |
ACC_FINAL | 0x0010 | final |
ACC_INTERFACE | 0x0200 | interface |
ACC_ABSTRACT | 0x0400 | abstract |
ACC_SYNTHETIC | 0x1000 | 非源码提供 |
ACC_ANNOTATION | 0x2000 | 注解类型 |
ACC_ENUM | 0x4000 | 枚举类型 |
- EnclosingMethod
EnclosingMethod_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "EnclosingMethod"
u4 attribute_length; // 4
u2 class_index; // CONSTANT_Utf8_info -> constant_pool
u2 method_index; // zero => current class is not immediately enclosed by a method or constructor
// CONSTANT_NameAndType_info -> constant_pool
}
- Synthetic
Synthetic_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "Synthetic"
u4 attribute_length; // must be zero
}
- Signature
Signature_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "Signature"
u4 attribute_length; // 2
u2 signature_index; // CONSTANT_Utf8_info -> constant_pool
}
MethodSignature:
[TypeParameters] ( {JavaTypeSignature} ) Result {ThrowsSignature}
- SourceFile
SourceFile_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "SourceFile"
u4 attribute_length; // 2
u2 sourcefile_index; // CONSTANT_Utf8_info -> constant_pool
}
- SourceDebugExtension
SourceDebugExtension_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "SourceDebugExtension"
u4 attribute_length; // excluding the initial six bytes
u1 debug_extension[attribute_length]; // modified UTF-8 string
}
- LineNumberTable
LineNumberTable_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "LineNumberTable"
u4 attribute_length; // excluding the initial six bytes
u2 line_number_table_length;
{
u2 start_pc; //
u2 line_number;
} line_number_table[line_number_table_length];
}
- LocalVariableTable
- 可以有多个,不要求顺序
LocalVariableTable_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "LocalVariableTable"
u4 attribute_length; // excluding the initial six bytes
u2 local_variable_table_length; // the number of entries in the local_variable_table array
{
u2 start_pc; // 局部变量的作用域:[start_pc, start_pc + length)
u2 length;
u2 name_index; // CONSTANT_Utf8_info -> constant_pool
u2 descriptor_index; // CONSTANT_Utf8_info -> constant_pool
u2 index; // 槽位,遇到long / double 顺延 + 1
} local_variable_table[local_variable_table_length];
}
- LocalVariableTypeTable
- 可以有多个,不要求顺序
LocalVariableTypeTable_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "LocalVariableTypeTable"
u4 attribute_length; // excluding the initial six bytes
u2 local_variable_type_table_length;
{
u2 start_pc; //
u2 length;
u2 name_index;
u2 signature_index; // CONSTANT_Utf8_info -> constant_pool
u2 index;
} local_variable_type_table[local_variable_type_table_length];
}
- Deprecated
Deprecated_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "Deprecated"
u4 attribute_length; // must be zero
}
- RuntimeVisibleAnnotations
RuntimeVisibleAnnotations_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "RuntimeVisibleAnnotations"
u4 attribute_length; // excluding the initial six bytes
u2 num_annotations; //
annotation annotations[num_annotations]; // annotation结构
}
annotation结构:
annotation {
u2 type_index; // CONSTANT_Utf8_info -> constant_pool -> descriptor
u2 num_element_value_pairs;
{
u2 element_name_index; // CONSTANT_Utf8_info -> constant_pool
element_value value; // element_value结构
} element_value_pairs[num_element_value_pairs];
}
element_value结构:
element_value {
u1 tag; // single ASCII
// Table 4.7.16.1-A
union {
u2 const_value_index; // CONSTANT_Utf8_info -> constant_pool
{
u2 type_name_index; // CONSTANT_Utf8_info -> constant_pool
u2 const_name_index;
} enum_const_value;
u2 class_info_index; // CONSTANT_Utf8_info -> constant_pool -> descriptor
// BaseType character
// void : V
annotation annotation_value; // nested annotation
{
u2 num_values;
element_value values[num_values];
} array_value; // element-value pair
} value;
}
Table 4.7.16.1-A. Interpretation of tag values as types
tag Item | Type | value Item | Constant Type |
---|---|---|---|
B | byte | const_value_index | CONSTANT_Integer |
C | char | const_value_index | CONSTANT_Integer |
D | double | const_value_index | CONSTANT_Double |
F | float | const_value_index | CONSTANT_Float |
I | int | const_value_index | CONSTANT_Integer |
J | long | const_value_index | CONSTANT_Long |
S | short | const_value_index | CONSTANT_Integer |
Z | boolean | const_value_index | CONSTANT_Integer |
s | String | const_value_index | CONSTANT_Utf8 |
e | Enum | type | enum_const_value |
c | Class | class_info_index | Not applicable |
@ | Annotation | type | annotation_value |
[ | Array | type | array_value |
- RuntimeInvisibleAnnotations
- 类似RuntimeVisibleAnnotations
RuntimeInvisibleAnnotations_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 num_annotations;
annotation annotations[num_annotations];
}
- RuntimeInvisibleParameterAnnotations
RuntimeInvisibleParameterAnnotations_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "RuntimeInvisibleParameterAnnotations"
u4 attribute_length;
u1 num_parameters;
{
u2 num_annotations;
annotation annotations[num_annotations];
} parameter_annotations[num_parameters];
}
- RuntimeVisibleTypeAnnotations
RuntimeVisibleTypeAnnotations_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "RuntimeVisibleTypeAnnotations"
u4 attribute_length;
u2 num_annotations;
type_annotation annotations[num_annotations]; // type_annotation结构
}
type_annotation结构:
type_annotation {
u1 target_type; // Table 4.7.20-A
// Table 4.7.20-B
// Table 4.7.20-C
union {
type_parameter_target;
supertype_target;
type_parameter_bound_target;
empty_target;
formal_parameter_target;
throws_target;
localvar_target;
catch_target;
offset_target;
type_argument_target;
} target_info; // target_info结构
type_path target_path; // type_path结构
u2 type_index;
u2 num_element_value_pairs;
{
u2 element_name_index;
element_value value;
} element_value_pairs[num_element_value_pairs];
}
target_info结构:
type_parameter_target {
u1 type_parameter_index;
}
supertype_target {
u2 supertype_index;
}
type_parameter_bound_target {
u1 type_parameter_index;
u1 bound_index;
}
empty_target {
}
formal_parameter_target {
u1 formal_parameter_index;
}
throws_target {
u2 throws_type_index;
}
localvar_target {
u2 table_length;
{
u2 start_pc;
u2 length;
u2 index;
} table[table_length];
}
catch_target {
u2 exception_table_index;
}
offset_target {
u2 offset;
}
type_argument_target {
u2 offset;
u1 type_argument_index;
}
type_path结构:
type_path {
u1 path_length;
{
u1 type_path_kind; // Table 4.7.20.2-A
u1 type_argument_index;
} path[path_length];
}
- RuntimeInvisibleTypeAnnotations
RuntimeInvisibleTypeAnnotations_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 num_annotations;
type_annotation annotations[num_annotations];
}
- AnnotationDefault
AnnotationDefault_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "AnnotationDefault"
u4 attribute_length; // excluding the initial six bytes
element_value default_value;
}
- BootstrapMethods
BootstrapMethods_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "BootstrapMethods"
u4 attribute_length; // excluding the initial six bytes
u2 num_bootstrap_methods;
{
u2 bootstrap_method_ref; // CONSTANT_MethodHandle_info
u2 num_bootstrap_arguments;
u2 bootstrap_arguments[num_bootstrap_arguments]; // constant_pool index
} bootstrap_methods[num_bootstrap_methods]; //
}
- MethodParameters
MethodParameters_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "MethodParameters"
u4 attribute_length; // excluding the initial six bytes
u1 parameters_count;
{
u2 name_index; // CONSTANT_Utf8_info -> constant_pool
u2 access_flags; // 0x0010 (ACC_FINAL)
// 0x1000 (ACC_SYNTHETIC)
// 0x8000 (ACC_MANDATED)
} parameters[parameters_count];
}
- Module
Module_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "Module"
u4 attribute_length; // excluding the initial six bytes
u2 module_name_index; // CONSTANT_Module_info -> constant_pool
u2 module_flags; // 0x0020 (ACC_OPEN)
// 0x1000 (ACC_SYNTHETIC)
// 0x8000 (ACC_MANDATED)
u2 module_version_index; // CONSTANT_Utf8_info -> constant_pool
u2 requires_count;
{
u2 requires_index; // CONSTANT_Module_info -> constant_pool
u2 requires_flags; // 0x0020 (ACC_TRANSITIVE)
// 0x0040 (ACC_STATIC_PHASE)
// 0x1000 (ACC_SYNTHETIC)
// 0x8000 (ACC_MANDATED)
u2 requires_version_index; // CONSTANT_Utf8_info -> constant_pool
} requires[requires_count];
u2 exports_count;
{
u2 exports_index; // CONSTANT_Package_info -> constant_pool
u2 exports_flags; // 0x1000 (ACC_SYNTHETIC)
// 0x8000 (ACC_MANDATED)
u2 exports_to_count;
u2 exports_to_index[exports_to_count]; // CONSTANT_Module_info -> constant_pool
} exports[exports_count];
u2 opens_count;
{
u2 opens_index; // CONSTANT_Package_info -> constant_pool
u2 opens_flags; // 0x1000 (ACC_SYNTHETIC)
// 0x8000 (ACC_MANDATED)
u2 opens_to_count;
u2 opens_to_index[opens_to_count]; // CONSTANT_Module_info -> constant_pool
} opens[opens_count];
u2 uses_count;
u2 uses_index[uses_count]; // CONSTANT_Class_info -> constant_pool
u2 provides_count;
{
u2 provides_index; // CONSTANT_Class_info -> constant_pool
u2 provides_with_count;
u2 provides_with_index[provides_with_count]; // CONSTANT_Class_info -> constant_pool
} provides[provides_count];
}
- ModulePackages
ModulePackages_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "ModulePackages"
u4 attribute_length; // excluding the initial six bytes
u2 package_count;
u2 package_index[package_count]; // CONSTANT_Package_info -> constant_pool
}
- ModuleMainClass
ModuleMainClass_attribute {
u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "ModuleMainClass"
u4 attribute_length; // excluding the initial six bytes
u2 main_class_index; // CONSTANT_Class_info -> constant_pool
}