深入解析:JVM字节码attribute_info

JVM字节码attribute_info

前言

最近写J2ME深感各种java反编译不得我心,决定自己尝试写一个自己的java反编译,第一步完成javap。现在拷贝官网文档运用ai翻译,贴出来,列举出各种属性类型,属性在字节码里面至关重要。其中表格特殊标记的RuntimeVisibleTypeAnnotations是刚实现读取的属性,还没贴出来。

4.7 属性

属性用于类文件格式中的 ClassFilefield_infomethod_infoCode_attributerecord_component_info 结构(§4.1、§4.5、§4.6、§4.7.3、§4.7.30)。

所有属性都遵循以下通用格式:

attribute_info {
    u2 attribute_name_index;
    u4 attribute_length;
    u1 info[attribute_length];
}

对于所有属性,attribute_name_index 项必须是类常量池中有效的无符号16位索引。常量池在 attribute_name_index 处的条目必须是一个 CONSTANT_Utf8_info 结构(§4.4.7),代表该属性的名称。attribute_length 项的值指示了后续信息的长度(以字节为单位)。该长度不包含包含 attribute_name_indexattribute_length 项的前六个字节。

本规范预定义了30个属性。为便于查阅,它们被列出三次:

  • 表4.7-A 按本章中属性所在章节编号排序。每个属性都展示了其首次定义的类文件格式版本,以及引入该版本类文件格式的 Java SE 平台版本(§4.1)。
  • 表4.7-B 按每个属性首次定义的类文件格式版本排序。
  • 表4.7-C 按每个属性在类记录中定义出现的位置排序。

在本规范的运用上下文中,即在其出现的类文件结构的属性表中,这些预定义属性的名称是保留的。

预定义属性在属性表中存在的任何条件都在描述该属性的章节中明确指定。如果未指定任何条件,则该属性许可在属性表中出现任意次数。

根据其用途,预定义的属性分为三组:

  1. 对 Java 虚拟机正确解释类资料至关重要的七个属性

    • ConstantValue
    • Code
    • StackMapTable
    • BootstrapMethods
    • NestHost
    • NestMembers
    • PermittedSubclasses

    在版本号为 v 的类文件中,如果 Java 虚拟机实现支持类文件格式的版本 v,并且该属性首次定义于类文件格式的版本 v 或更早版本,并且该属性出现在其定义出现的位置,则该实现必须识别并正确读取这些属性中的每一个。

  2. 对 Java 虚拟机正确解释类文件不关键,但对 Java SE 平台类库正确解释类文件至关重要,或对工具有用的十个属性(在这种情况下,规定属性的章节将其描述为"可选的"):

    • Exceptions
    • InnerClasses
    • EnclosingMethod
    • Synthetic
    • Signature
    • Record
    • SourceFile
    • LineNumberTable
    • LocalVariableTable
    • LocalVariableTypeTable

    在版本号为 v 的类文件中,如果 Java 虚拟机实现支持类文件格式的版本 v,并且该属性首次定义于类文件格式的版本 v 或更早版本,并且该属性出现在其定义出现的位置,则该实现必须识别并正确读取这些属性中的每一个。

  3. 对 Java 虚拟机正确解释类文件不关键,但包含关于类文件的元数据的十三个属性,这些元数据要么由 Java SE 平台的类库公开,要么由软件献出(在这种情况下,规定属性的章节将其描述为"可选的"):

    • SourceDebugExtension
    • Deprecated
    • RuntimeVisibleAnnotations
    • RuntimeInvisibleAnnotations
    • RuntimeVisibleParameterAnnotations
    • RuntimeInvisibleParameterAnnotations
    • RuntimeVisibleTypeAnnotations
    • RuntimeInvisibleTypeAnnotations
    • AnnotationDefault
    • MethodParameters
    • Module
    • ModulePackages
    • ModuleMainClass

    Java 虚拟机建立许可使用这些属性包含的信息,否则必须静默忽略这些属性。

表4.7-A. 预定义的类文件属性(按章节排序)

属性章节类文件版本Java SE文档链接
ConstantValue§4.7.245.31.0.2
Code§4.7.345.31.0.2
StackMapTable§4.7.450.06
Exceptions§4.7.545.31.0.2
InnerClasses§4.7.645.31.1
EnclosingMethod§4.7.749.05.0
Synthetic§4.7.845.31.1
Signature§4.7.949.05.0
SourceFile§4.7.1045.31.0.2
SourceDebugExtension§4.7.1149.05.0
LineNumberTable§4.7.1245.31.0.2
LocalVariableTable§4.7.1345.31.0.2
LocalVariableTypeTable§4.7.1449.05.0
Deprecated§4.7.1545.31.1
RuntimeVisibleAnnotations§4.7.1649.05.0
RuntimeInvisibleAnnotations§4.7.1749.05.0
RuntimeVisibleParameterAnnotations§4.7.1849.05.0
RuntimeInvisibleParameterAnnotations§4.7.1949.05.0
RuntimeVisibleTypeAnnotations§4.7.2052.08RuntimeVisibleTypeAnnotations
RuntimeInvisibleTypeAnnotations§4.7.2152.08
AnnotationDefault§4.7.2249.05.0
BootstrapMethods§4.7.2351.07
MethodParameters§4.7.2452.08
Module§4.7.2553.09
ModulePackages§4.7.2653.09
ModuleMainClass§4.7.2753.09
NestHost§4.7.2855.011
NestMembers§4.7.2955.011
Record§4.7.3060.016
PermittedSubclasses§4.7.3161.017

表4.7-B. 预定义的类文件属性(按类文件格式版本排序)

属性类文件版本Java SE章节
ConstantValue45.31.0.2§4.7.2
Code45.31.0.2§4.7.3
Exceptions45.31.0.2§4.7.5
SourceFile45.31.0.2§4.7.10
LineNumberTable45.31.0.2§4.7.12
LocalVariableTable45.31.0.2§4.7.13
InnerClasses45.31.1§4.7.6
Synthetic45.31.1§4.7.8
Deprecated45.31.1§4.7.15
EnclosingMethod49.05.0§4.7.7
Signature49.05.0§4.7.9
SourceDebugExtension49.05.0§4.7.11
LocalVariableTypeTable49.05.0§4.7.14
RuntimeVisibleAnnotations49.05.0§4.7.16
RuntimeInvisibleAnnotations49.05.0§4.7.17
RuntimeVisibleParameterAnnotations49.05.0§4.7.18
RuntimeInvisibleParameterAnnotations49.05.0§4.7.19
AnnotationDefault49.05.0§4.7.22
StackMapTable50.06§4.7.4
BootstrapMethods51.07§4.7.23
RuntimeVisibleTypeAnnotations52.08§4.7.20
RuntimeInvisibleTypeAnnotations52.08§4.7.21
MethodParameters52.08§4.7.24
Module53.09§4.7.25
ModulePackages53.09§4.7.26
ModuleMainClass53.09§4.7.27
NestHost55.011§4.7.28
NestMembers55.011§4.7.29
Record60.016§4.7.30
PermittedSubclasses61.017§4.7.31

表4.7-C. 预定义的类文件属性(按位置排序)

属性位置类文件版本
SourceFileClassFile45.3
InnerClassesClassFile45.3
EnclosingMethodClassFile49.0
SourceDebugExtensionClassFile49.0
BootstrapMethodsClassFile51.0
Module, ModulePackages, ModuleMainClassClassFile53.0
NestHost, NestMembersClassFile55.0
RecordClassFile60.0
PermittedSubclassesClassFile61.0
ConstantValuefield_info45.3
Codemethod_info45.3
Exceptionsmethod_info45.3
RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotationsmethod_info49.0
AnnotationDefaultmethod_info49.0
MethodParametersmethod_info52.0

表4.7-C (续). 预定义的类文件属性(按位置排序)

属性位置类文件版本
SyntheticClassFile, field_info, method_info45.3
DeprecatedClassFile, field_info, method_info45.3
SignatureClassFile, field_info, method_info, record_component_info49.0
RuntimeVisibleAnnotations, RuntimeInvisibleAnnotationsClassFile, field_info, method_info, record_component_info49.0
LineNumberTableCode45.3
LocalVariableTableCode45.3
LocalVariableTypeTableCode49.0
StackMapTableCode50.0
RuntimeVisibleTypeAnnotations, RuntimeInvisibleTypeAnnotationsClassFile, field_info, method_info, Code, record_component_info52.0

4.7.1. 定义和命名新属性

允许编译器在类文件结构、field_info 结构、method_info 结构和 Code 属性(§4.7.3)的属性表中定义并发出包含新属性的类文件。允许 Java 虚拟机实现在这些属性表中识别和使用新属性。但是,任何未定义为本规范一部分的属性不得影响类文件的语义。要求 Java 虚拟机实现静默忽略它们不认识的属性。

例如,允许定义一个新的属性来支持特定于供应商的调试。因为要求 Java 虚拟机构建忽略它们不认识的属性,所以针对该特定 Java 虚拟机实现的类文件将可以被其他实现使用,即使这些实现无法利用类文件中囊括的额外调试信息。

特别禁止 Java 虚拟机实现仅仅因为存在某些新属性而抛出异常或以其他方式拒绝利用类文件。当然,要是提供给工具的类文件不涵盖它们需要的所有属性,那么这些操作类文件的应用可能无法正确运行。

两个本意不同但恰巧应用相同属性名称且长度相同的属性,在能识别任一属性的实现上会产生冲突。本规范之外定义的属性应根据Java 语言规范 Java SE 25 版(JLS §6.1) 中描述的包命名约定来选择合适的名称。

本规范的未来版本可能会定义额外的属性。

参考文档 oracel java25文档
本文由deepseek翻译

posted @ 2026-01-04 12:39  clnchanpin  阅读(5)  评论(0)    收藏  举报