附加屬性(Attributes)被用於ClassFile, field_info, method_info,Code_attribute結構中。bootstrap
數據結構:數組
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的主類 | 可選,元數據,JavaSEapp
ConstantValue_attribute { u2 attribute_name_index; //CONSTANT_Utf8_info u4 attribute_length; u2 constantvalue_index; //constant_pool中的一個值 }
Constant value attribute types:ide
Field Type | Entry Type |
---|---|
long | CONSTANT_Long |
float | CONSTANT_Float |
double | CONSTANT_Double |
int, short, char, byte, boolean | CONSTANT_Integer |
String | CONSTANT_String |
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_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:ui
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_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_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_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_attribute { u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "Synthetic" u4 attribute_length; // must be zero }
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_attribute { u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "SourceFile" u4 attribute_length; // 2 u2 sourcefile_index; // CONSTANT_Utf8_info -> constant_pool }
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_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_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_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_attribute { u2 attribute_name_index; // CONSTANT_Utf8_info -> constant_pool -> "Deprecated" u4 attribute_length; // must be zero }
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結構:debug
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結構:code
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 typesorm
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_attribute { u2 attribute_name_index; u4 attribute_length; u2 num_annotations; annotation annotations[num_annotations]; }
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_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_attribute { u2 attribute_name_index; u4 attribute_length; u2 num_annotations; type_annotation annotations[num_annotations]; }
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_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_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_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_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_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 }