4.7. Attributes

  • Attributes are used in the ClassFile, field_info, method_info, and Code_attribute structures of the class file format.
attribute_info {
    u2 attribute_name_index; // constant_pool index, CONSTANT_Utf8_info structure
    u4 attribute_length;
    u1 info[attribute_length];
}
  • 23 attributes are predefined by this specification.


    Predefined class file attributes (by location)
  • The predefined attributes are categorized into three groups according to their purpose:

  1. Critical to correct interpretation of the class file by the JVM, 5 attributes:
    ConstantValue, Code, StackMapTable, Exceptions, BootstrapMethods
  2. Critical to correct interpretation of the class file by the class libraries of the Java SE platform, 12 attributes:
    InnerClasses, EnclosingMethod, Synthetic, Signature
    RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations
    RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations
    RuntimeVisibleTypeAnnotations, RuntimeInvisibleTypeAnnotations
    AnnotationDefault, MethodParameters
  3. Useful for tools, 6 attributes:
    SourceFile, SourceDebugExtension, Deprecated
    LineNumberTable, LocalVariableTable, LocalVariableTypeTable

4.7.1 Defining and Naming New Attributes

  • Compilers are permitted to define and emit class files containing new attributes in the attributes tables of class file structures, field_info structures, method_info structures, and Code attributes.
  • JVM implementations are permitted to recognize and use new attributes found in these attributes tables.

4.7.2 The ConstantValue Attribute

  • There may be at most one ConstantValue attribute in the attributes table of a field_info structure.
ConstantValue_attribute {
    u2 attribute_name_index; // ConstantValue
    u4 attribute_length; // 2
    u2 constantvalue_index; // constant_pool index
}

constantvalue_index
The constant_pool entry must be of a type appropriate to the field.

Constant value attribute types


4.7.3 The Code Attribute

  • If the method is either native or abstract, its method_info structure must not have a Code attribute in its attributes table.
  • Otherwise, its method_info structure must have exactly one Code attribute in its attributes table.
Code_attribute {
    u2 attribute_name_index; // Code
    u4 attribute_length;
    u2 max_stack;
    u2 max_locals;
    u4 code_length;
    u1 code[code_length];
    u2 exception_table_length;
    {   u2 start_pc; // code array index
        u2 end_pc; // code array index
        u2 handler_pc; // code array index
        u2 catch_type; // zero or constant_pool index, CONSTANT_Class_info structure
    } exception_table[exception_table_length];
    u2 attributes_count;
    attribute_info attributes[attributes_count];
}

exception_table[exception_table_length]

  • Each entry in the exception_table array describes one exception handler in the code array.
  • The order of the handlers in the exception_table array is significant.
  • The start_pc and end_pc indicate the ranges in the code array at which the exception handler is active, with the program counter is within the interval [start_pc, end_pc).

4.7.4 The StackMapTable Attribute

  • A StackMapTable attribute is used during the process of verification by type checking.
  • When version number >= 50.0, if a method's Code attribute does not have a StackMapTable attribute, it has an implicit stack map attribute, which is equivalent to a zero-lengthed StackMapTable attribute.
StackMapTable_attribute {
    u2 attribute_name_index; // StackMapTable
    u4 attribute_length;
    u2 number_of_entries;
    stack_map_frame entries[number_of_entries];
}

entries[number_of_entries]

  • Each entry in the entries table describes one stack map frame of the method.
  • The order of the stack map frames in the entries table is significant.
  • A stack map frame specifies (either explicitly or implicitly)
    • the bytecode offset at which it applies,
    • the verification types of local variables and operand stack entries for that offset.
  • The first stack map frame of a method is implicit, and computed from the method descriptor by the type checker.

bytecode offset

  • bytecode offset = bytecode offset of the previous frame + (offset_delta + 1)
  • offset delta VS. actual bytecode offset
    • Stack map frames are in the correctly sorted order.
    • Guarantees the absence of duplicates, by using offset_delta + 1

verification_type_info

  • A verification type specifies the type of either one or two locations, where a location is either a single local variable or a single operand stack entry.
  • A verification type is represented by a discriminated union, verification_type_info, that consists of:
    • a one-byte tag, indicating which item of the union is in use,
    • followed by zero or more bytes, giving more information about the tag.
union verification_type_info {
    Top_variable_info; // tag = ITEM_Top; /* 0 */
    Integer_variable_info; // tag = ITEM_Integer; /* 1 */
    Float_variable_info; // tag = ITEM_Float; /* 2 */
    Long_variable_info; // tag = ITEM_Long; /* 4 */
    Double_variable_info; // tag = ITEM_Double; /* 3 */
    Null_variable_info; // tag = ITEM_Null; /* 5 */
    UninitializedThis_variable_info; // tag = ITEM_UninitializedThis; /* 6 */
    Object_variable_info; // tag = ITEM_Object; /* 7 */
    Uninitialized_variable_info; // tag = ITEM_Uninitialized; /* 8 */
}
Object_variable_info {
    u1 tag = ITEM_Object; /* 7 */
    u2 cpool_index; // CONSTANT_Class_info structure
}
Uninitialized_variable_info {
    u1 tag = ITEM_Uninitialized; /* 8 */
    u2 offset;
}

stack_map_frame

  • A stack map frame is represented by a discriminated union, stack_map_frame, which consists of:
    • a one-byte tag, indicating which item of the union is in use,
    • followed by zero or more bytes, giving more information about the tag.
  • The tag indicates the frame type of the stack map frame.
union stack_map_frame {
    same_frame; // frame_type = SAME; /* 0-63 */
    same_locals_1_stack_item_frame;
    same_locals_1_stack_item_frame_extended;
    chop_frame;
    same_frame_extended;
    append_frame;
    full_frame;
}
same_locals_1_stack_item_frame {
    u1 frame_type = SAME_LOCALS_1_STACK_ITEM; /* 64-127 */
    verification_type_info stack[1];
}
// Tags in the range [128-246] are reserved for future use.
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];
}
full_frame {
    u1 frame_type = FULL_FRAME; /* 255 */
    u2 offset_delta;
    u2 number_of_locals;
    verification_type_info locals[number_of_locals];
    u2 number_of_stack_items;
    verification_type_info stack[number_of_stack_items];
}

4.7.5 The Exceptions Attribute

Exceptions_attribute {
    u2 attribute_name_index; // Exceptions
    u4 attribute_length;
    u2 number_of_exceptions;
    u2 exception_index_table[number_of_exceptions];
    // constant_pool index, CONSTANT_Class_info structure
}

4.7.6 The InnerClasses Attribute

InnerClasses_attribute {
    u2 attribute_name_index; // InnerClasses".
    u4 attribute_length;
    u2 number_of_classes;
    {   u2 inner_class_info_index; // constant_pool index, CONSTANT_Class_info structure
        u2 outer_class_info_index; // zero or constant_pool index, CONSTANT_Class_info structure
        u2 inner_name_index; // zero or constant_pool index, CONSTANT_Utf8_info structure
        u2 inner_class_access_flags;
    } classes[number_of_classes];
}

classes[number_of_classes]
Every CONSTANT_Class_info entry in the constant_pool table which represents a class or interface C that is NOT a package member must have exactly one corresponding entry in the classes array.

inner_class_access_flags

  • The value of the inner_class_access_flags item is a mask of flags used to denote access permissions to and properties of class or interface C as declared in the source code from which this class file was compiled.
Nested class access and property flags

4.7.7 The EnclosingMethod Attribute

  • A class must have an EnclosingMethod attribute if and only if it represents a local class or an anonymous class.
EnclosingMethod_attribute {
    u2 attribute_name_index; // EnclosingMethod
    u4 attribute_length; // 4
    u2 class_index; // constant_pool index, CONSTANT_Class_info structure
    u2 method_index; // zero or constant_pool index, CONSTANT_NameAndType_info structure
}

method_index

  • If the current class is not immediately enclosed by a method or constructor, then the value of the method_index item must be zero. In particular, the current class was immediately enclosed by:
    • instance initializer,
    • static initializer,
    • instance variable initializer,
    • or class variable initializer.

4.7.8 The Synthetic Attribute

Synthetic_attribute {
    u2 attribute_name_index; // Synthetic
    u4 attribute_length; // 0
}

4.7.9 The Signature Attribute

  • A Signature attribute records a signature for a class, interface, constructor, method, or field whose declaration in the Java programming language uses type variables or parameterized types.
Signature_attribute {
    u2 attribute_name_index; // Signature
    u4 attribute_length; // 2
    u2 signature_index; // constant_pool index, CONSTANT_Utf8_info structure
}

Signatures

  • A Java compiler must emit a signature for any class, interface, constructor, method, or field whose declaration uses type variables or parameterized types.

  • Signatures are specified using a grammar which follows the notation of §4.3.1. In addition to that notation:

    • [x]: zero or one occurrences of x. optional symbol
  • The grammar includes the terminal symbol Identifier to denote the name of a type, field, method, formal parameter, local variable, or type variable, as generated by a Java compiler.

  • Such a name must not contain any of the ASCII characters . ; [ / < > :.

  • Signatures rely on a hierarchy of nonterminals known as type signatures.

§ 4.3
BaseType: (one of) B C D F I J S Z
VoidDescriptor: V

ReferenceTypeSignature

JavaTypeSignature: ReferenceTypeSignature | BaseType
ReferenceTypeSignature: ClassTypeSignature | TypeVariableSignature | ArrayTypeSignature

ClassTypeSignature

ClassTypeSignature: L [PackageSpecifier] SimpleClassTypeSignature {ClassTypeSignatureSuffix} ;
PackageSpecifier: Identifier / {PackageSpecifier}
SimpleClassTypeSignature: Identifier [TypeArguments]
TypeArguments: < TypeArgument {TypeArgument} >
TypeArgument: [WildcardIndicator] ReferenceTypeSignature | *
WildcardIndicator: + | -
ClassTypeSignatureSuffix: . SimpleClassTypeSignature

TypeVariableSignature

TypeVariableSignature: T Identifier ;

ArrayTypeSignature

ArrayTypeSignature: [ JavaTypeSignature

ClassSignature

ClassSignature: [TypeParameters] SuperclassSignature {SuperinterfaceSignature}
TypeParameters: < TypeParameter {TypeParameter} >
TypeParameter: Identifier ClassBound {InterfaceBound}
ClassBound: : [ReferenceTypeSignature]
InterfaceBound: : ReferenceTypeSignature
SuperclassSignature: ClassTypeSignature
SuperinterfaceSignature: ClassTypeSignature

MethodSignature

MethodSignature: [TypeParameters] ( {JavaTypeSignature} ) Result {ThrowsSignature}
Result: JavaTypeSignature | VoidDescriptor
ThrowsSignature: ^ ClassTypeSignature | ^ TypeVariableSignature

FieldSignature

  • A field signature encodes the (possibly parameterized) type of a field, formal parameter, or local variable declaration.

FieldSignature: ReferenceTypeSignature


4.7.10 The SourceFile Attribute (optional)

SourceFile_attribute {
    u2 attribute_name_index; // SourceFile
    u4 attribute_length; // 2
    u2 sourcefile_index; // constant_pool index, CONSTANT_Utf8_info structure
}

4.7.11 The SourceDebugExtension Attribute (optional)

SourceDebugExtension_attribute {
    u2 attribute_name_index; // SourceDebugExtension
    u4 attribute_length;
    u1 debug_extension[attribute_length]; // using a modified UTF-8 string
}

4.7.12 The LineNumberTable Attribute (optional)

  • If multiple LineNumberTable attributes are present in the attributes table of a Code attribute, then they may appear in any order.
LineNumberTable_attribute {
    u2 attribute_name_index; // LineNumberTable
    u4 attribute_length;
    u2 line_number_table_length;
    {   u2 start_pc; // code array index
        u2 line_number;
    } line_number_table[line_number_table_length];
}

4.7.13 The LocalVariableTable Attribute (optional)

  • If multiple LocalVariableTable attributes are present in the attributes table of a Code attribute, then they may appear in any order.
  • There may be no more than one LocalVariableTable attribute per local variable in the attributes table of a Code attribute.
LocalVariableTable_attribute {
    u2 attribute_name_index; // LocalVariableTable
    u4 attribute_length;
    u2 local_variable_table_length;
    {   u2 start_pc; // code array index
        u2 length;
        u2 name_index; // constant_pool index, CONSTANT_Utf8_info structure
        u2 descriptor_index; // constant_pool index, CONSTANT_Utf8_info structure
        u2 index; // local variable array index
    } local_variable_table[local_variable_table_length];
}

local_variable_table[local_variable_table_length]

  • Each entry in the local_variable_table array indicates a range of code array offsets within which a local variable has a value.
  • It also indicates the index into the local variable array of the current frame at which that local variable can be found.

start_pc, length: The given local variable must have a value at indices into the code array in the interval [start_pc, start_pc + length).

index: The given local variable must be at index in the local variable array of the current frame.


4.7.14 The LocalVariableTypeTable Attribute (optional)

  • If multiple LocalVariableTypeTable attributes are present in the attributes table of a given Code attribute, then they may appear in any order.
  • There may be no more than one LocalVariableTypeTable attribute per local variable in the attributes table of a Code attribute.
LocalVariableTypeTable_attribute {
    u2 attribute_name_index; // LocalVariableTypeTable
    u4 attribute_length;
    u2 local_variable_type_table_length;
    {   u2 start_pc;  // code array index
        u2 length;
        u2 name_index; // constant_pool index, CONSTANT_Utf8_info structure
        u2 signature_index; // constant_pool index, CONSTANT_Utf8_info structure
        u2 index; // local variable array index
    } local_variable_type_table[local_variable_type_table_length];
}

LocalVariableTypeTable VS. LocalVariableTable

  • LocalVariableTypeTable provides information about signature rather than descriptor.
  • This difference is only significant for variables whose type uses a type variable or parameterized type.
  • Such variables will appear in both tables, while variables of other types will appear only in LocalVariableTable.

4.7.15 The Deprecated Attribute (optional)

Deprecated_attribute {
    u2 attribute_name_index; // Deprecated
    u4 attribute_length; // 0
}

4.7.16 The RuntimeVisibleAnnotations Attribute

RuntimeVisibleAnnotations_attribute {
    u2 attribute_name_index; // RuntimeVisibleAnnotations
    u4 attribute_length;
    u2 num_annotations;
    annotation annotations[num_annotations];
}
annotation {
    u2 type_index; // constant_pool index, CONSTANT_Utf8_info structur
    u2 num_element_value_pairs;
    {   u2 element_name_index; // constant_pool index, CONSTANT_Utf8_info structur
        element_value value;
    } element_value_pairs[num_element_value_pairs];
}

element_value

element_value {
    u1 tag;
    union {
        u2 const_value_index;
        {   u2 type_name_index;
            u2 const_name_index;
        } enum_const_value;
        u2 class_info_index;
        annotation annotation_value; // a "nested" annotation
        {   u2 num_values;
            element_value values[num_values];
        } array_value;
    } value;
}

tag

Interpretation of tag values as types

4.7.17 The RuntimeInvisibleAnnotations Attribute

RuntimeInvisibleAnnotations_attribute {
    u2 attribute_name_index; // RuntimeInvisibleAnnotations
    u4 attribute_length;
    u2 num_annotations;
    annotation annotations[num_annotations];
}

4.7.18 The RuntimeVisibleParameterAnnotations Attribute

RuntimeVisibleParameterAnnotations_attribute {
    u2 attribute_name_index; // RuntimeVisibleParameterAnnotations
    u4 attribute_length;
    u1 num_parameters;
    {   u2 num_annotations;
        annotation annotations[num_annotations];
    } parameter_annotations[num_parameters];
}

4.7.19 The RuntimeInvisibleParameterAnnotations Attribute

RuntimeInvisibleParameterAnnotations_attribute {
    u2 attribute_name_index; // RuntimeInvisibleParameterAnnotations
    u4 attribute_length;
    u1 num_parameters;
    {   u2 num_annotations;
        annotation annotations[num_annotations];
    } parameter_annotations[num_parameters];
}

4.7.20 The RuntimeVisibleTypeAnnotations Attribute

RuntimeVisibleTypeAnnotations_attribute {
    u2 attribute_name_index; //RuntimeVisibleTypeAnnotations
    u4 attribute_length;
    u2 num_annotations;
    type_annotation annotations[num_annotations];
}

type_annotation

type_annotation {
    // specify the precise location of the annotated type
    u1 target_type;
    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;
    type_path target_path;
    // specify the annotation's own type and element-value pairs
    u2 type_index; // constant_pool index, CONSTANT_Utf8_info structur
    u2 num_element_value_pairs;
    {   u2 element_name_index;
        element_value value;
    } element_value_pairs[num_element_value_pairs];
}

target_type

  • The various kinds of target correspond to the type contexts of the Java programming language where types are used in declarations and expressions.
Interpretation of target_type values (Part 1)
Interpretation of target_type values (Part 2)
Location of enclosing attribute for target_type values

The target_info union

// repeated from type_annotation 
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;
//-----------------------------------------
type_parameter_target {
    u1 type_parameter_index; // declaration of the i'th type parameter, zero based
}
supertype_target {
    u2 supertype_index; // 65535 or interfaces array index, a type in
the extends or implements clause
}
type_parameter_bound_target {
    u1 type_parameter_index;
    u1 bound_index;
}
empty_target {
    // the type in a field declaration,
    // the return type of a method,
    // the type of a newly constructed object,
    // the receiver type of a method or constructor
}
formal_parameter_target {
    u1 formal_parameter_index; // method, constructor, or lambda expression
}
throws_target {
    u2 throws_type_index; // exception_index_table array index
}
localvar_target {
    u2 table_length;
    {   u2 start_pc;
        u2 length;
        u2 index; // local variable index
    } table[table_length];
}
catch_target {
    u2 exception_table_index; // exception_table array index
}
offset_target {
    u2 offset; // code array index, instanceof, new, method reference(::)
}
type_argument_target {
    u2 offset; // code array index
    u1 type_argument_index;
}

The type_path structure

type_path {
    u1 path_length;
    {   u1 type_path_kind;
        u1 type_argument_index;
    } path[path_length];
}
  • array type T[]
@Foo String[][] // Annotates the class type String
String @Foo [][] // Annotates the array type String[][]
String[] @Foo [] // Annotates the array type String[]
  • nested type T1.T2
@Foo Outer.Middle.Inner
Outer.@Foo Middle.Inner
Outer.Middle.@Foo Inner
  • parameterized type T<A> or T<? extends A> or T<? super A>
@Foo Map<String, Object>
Map<@Foo String, Object>
Map<String, @Foo Object>
List<@Foo ? extends String>
List<? extends @Foo String>
  • type_path_kind
Interpretation of type_path_kind values
  • type_argument_index
    • type_path_kind: 0, 1, 2 → type_argument_index: 0
    • type_path_kind: 3 → type_argument_index: specifies the annotated type argument of a parameterized type

4.7.21 The RuntimeInvisibleTypeAnnotations Attribute

RuntimeInvisibleTypeAnnotations_attribute {
    u2 attribute_name_index; // RuntimeInvisibleTypeAnnotations
    u4 attribute_length;
    u2 num_annotations;
    type_annotation annotations[num_annotations];
}

4.7.22 The AnnotationDefault Attribute

The AnnotationDefault attribute is a variable-length attribute in the attributes table of certain method_info structures, namely those representing elements of annotation types.

AnnotationDefault_attribute {
    u2 attribute_name_index; // AnnotationDefault
    u4 attribute_length;
    element_value default_value;
}

4.7.23 The BootstrapMethods Attribute

The BootstrapMethods attribute records bootstrap method specifiers referenced by invokedynamic instructions.

BootstrapMethods_attribute {
    u2 attribute_name_index; // BootstrapMethods
    u4 attribute_length;
    u2 num_bootstrap_methods;
    {   u2 bootstrap_method_ref; // constant_pool index, CONSTANT_MethodHandle_info structur
        u2 num_bootstrap_arguments;
        // constant_pool index, CONSTANT_String_info structur
        u2 bootstrap_arguments[num_bootstrap_arguments];
    } bootstrap_methods[num_bootstrap_methods];
}

4.7.24 The MethodParameters Attribute

A MethodParameters attribute records information about the formal parameters of a method, such as their names.

MethodParameters_attribute {
    u2 attribute_name_index; // MethodParameters
    u4 attribute_length;
    u1 parameters_count;
    {   u2 name_index; // zero or constant_pool index, CONSTANT_Class_info structure
        u2 access_flags;
    } parameters[parameters_count];
}

access_flags

  • 0x0010 (ACC_FINAL): declared final
  • 0x1000 (ACC_SYNTHETIC): not explicitly or implicitly declared in source code
  • 0x8000 (ACC_MANDATED): implicitly declared in source code
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。