JVM字节码attribute_info
前言
最近写J2ME深感各种java反编译不得我心,决定自己尝试写一个自己的java反编译,第一步实现javap。现在拷贝官网文档使用ai翻译,贴出来,列举出各种属性类型,属性在字节码里面至关重要。其中表格特殊标记的RuntimeVisibleTypeAnnotations是刚实现读取的属性,还没贴出来。
4.7 属性
属性用于类文件格式中的 ClassFile、field_info、method_info、Code_attribute 和 record_component_info 结构(§4.1、§4.5、§4.6、§4.7.3、§4.7.30)。
所有属性都遵循以下通用格式:
c++
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_index 和 attribute_length 项的前六个字节。
本规范预定义了30个属性。为便于查阅,它们被列出三次:
- 表4.7-A 按本章中属性所在章节编号排序。每个属性都显示了其首次定义的类文件格式版本,以及引入该版本类文件格式的 Java SE 平台版本(§4.1)。
- 表4.7-B 按每个属性首次定义的类文件格式版本排序。
- 表4.7-C 按每个属性在类文件中定义出现的位置排序。
在本规范的使用上下文中,即在其出现的类文件结构的属性表中,这些预定义属性的名称是保留的。
预定义属性在属性表中存在的任何条件都在描述该属性的章节中明确指定。如果未指定任何条件,则该属性可以在属性表中出现任意次数。
根据其用途,预定义的属性分为三组:
-
对 Java 虚拟机正确解释类文件至关重要的七个属性:
ConstantValueCodeStackMapTableBootstrapMethodsNestHostNestMembersPermittedSubclasses
在版本号为
v的类文件中,如果 Java 虚拟机实现支持类文件格式的版本v,并且该属性首次定义于类文件格式的版本v或更早版本,并且该属性出现在其定义出现的位置,则该实现必须识别并正确读取这些属性中的每一个。 -
对 Java 虚拟机正确解释类文件不关键,但对 Java SE 平台类库正确解释类文件至关重要,或对工具有用的十个属性(在这种情况下,规定属性的章节将其描述为"可选的"):
ExceptionsInnerClassesEnclosingMethodSyntheticSignatureRecordSourceFileLineNumberTableLocalVariableTableLocalVariableTypeTable
在版本号为
v的类文件中,如果 Java 虚拟机实现支持类文件格式的版本v,并且该属性首次定义于类文件格式的版本v或更早版本,并且该属性出现在其定义出现的位置,则该实现必须识别并正确读取这些属性中的每一个。 -
对 Java 虚拟机正确解释类文件不关键,但包含关于类文件的元数据的十三个属性,这些元数据要么由 Java SE 平台的类库公开,要么由工具提供(在这种情况下,规定属性的章节将其描述为"可选的"):
SourceDebugExtensionDeprecatedRuntimeVisibleAnnotationsRuntimeInvisibleAnnotationsRuntimeVisibleParameterAnnotationsRuntimeInvisibleParameterAnnotationsRuntimeVisibleTypeAnnotationsRuntimeInvisibleTypeAnnotationsAnnotationDefaultMethodParametersModuleModulePackagesModuleMainClass
Java 虚拟机实现可以使用这些属性包含的信息,否则必须静默忽略这些属性。
表4.7-A. 预定义的类文件属性(按章节排序)
| 属性 | 章节 | 类文件版本 | Java SE | 文档链接 |
|---|---|---|---|---|
| ConstantValue | §4.7.2 | 45.3 | 1.0.2 | |
| Code | §4.7.3 | 45.3 | 1.0.2 | |
| StackMapTable | §4.7.4 | 50.0 | 6 | |
| Exceptions | §4.7.5 | 45.3 | 1.0.2 | |
| InnerClasses | §4.7.6 | 45.3 | 1.1 | |
| EnclosingMethod | §4.7.7 | 49.0 | 5.0 | |
| Synthetic | §4.7.8 | 45.3 | 1.1 | |
| Signature | §4.7.9 | 49.0 | 5.0 | |
| SourceFile | §4.7.10 | 45.3 | 1.0.2 | |
| SourceDebugExtension | §4.7.11 | 49.0 | 5.0 | |
| LineNumberTable | §4.7.12 | 45.3 | 1.0.2 | |
| LocalVariableTable | §4.7.13 | 45.3 | 1.0.2 | |
| LocalVariableTypeTable | §4.7.14 | 49.0 | 5.0 | |
| Deprecated | §4.7.15 | 45.3 | 1.1 | |
| RuntimeVisibleAnnotations | §4.7.16 | 49.0 | 5.0 | |
| RuntimeInvisibleAnnotations | §4.7.17 | 49.0 | 5.0 | |
| RuntimeVisibleParameterAnnotations | §4.7.18 | 49.0 | 5.0 | |
| RuntimeInvisibleParameterAnnotations | §4.7.19 | 49.0 | 5.0 | |
| RuntimeVisibleTypeAnnotations | §4.7.20 | 52.0 | 8 | RuntimeVisibleTypeAnnotations |
| RuntimeInvisibleTypeAnnotations | §4.7.21 | 52.0 | 8 | |
| AnnotationDefault | §4.7.22 | 49.0 | 5.0 | |
| BootstrapMethods | §4.7.23 | 51.0 | 7 | |
| MethodParameters | §4.7.24 | 52.0 | 8 | |
| Module | §4.7.25 | 53.0 | 9 | |
| ModulePackages | §4.7.26 | 53.0 | 9 | |
| ModuleMainClass | §4.7.27 | 53.0 | 9 | |
| NestHost | §4.7.28 | 55.0 | 11 | |
| NestMembers | §4.7.29 | 55.0 | 11 | |
| Record | §4.7.30 | 60.0 | 16 | |
| PermittedSubclasses | §4.7.31 | 61.0 | 17 |
表4.7-B. 预定义的类文件属性(按类文件格式版本排序)
| 属性 | 类文件版本 | Java SE | 章节 |
|---|---|---|---|
| ConstantValue | 45.3 | 1.0.2 | §4.7.2 |
| Code | 45.3 | 1.0.2 | §4.7.3 |
| Exceptions | 45.3 | 1.0.2 | §4.7.5 |
| SourceFile | 45.3 | 1.0.2 | §4.7.10 |
| LineNumberTable | 45.3 | 1.0.2 | §4.7.12 |
| LocalVariableTable | 45.3 | 1.0.2 | §4.7.13 |
| InnerClasses | 45.3 | 1.1 | §4.7.6 |
| Synthetic | 45.3 | 1.1 | §4.7.8 |
| Deprecated | 45.3 | 1.1 | §4.7.15 |
| EnclosingMethod | 49.0 | 5.0 | §4.7.7 |
| Signature | 49.0 | 5.0 | §4.7.9 |
| SourceDebugExtension | 49.0 | 5.0 | §4.7.11 |
| LocalVariableTypeTable | 49.0 | 5.0 | §4.7.14 |
| RuntimeVisibleAnnotations | 49.0 | 5.0 | §4.7.16 |
| RuntimeInvisibleAnnotations | 49.0 | 5.0 | §4.7.17 |
| RuntimeVisibleParameterAnnotations | 49.0 | 5.0 | §4.7.18 |
| RuntimeInvisibleParameterAnnotations | 49.0 | 5.0 | §4.7.19 |
| AnnotationDefault | 49.0 | 5.0 | §4.7.22 |
| StackMapTable | 50.0 | 6 | §4.7.4 |
| BootstrapMethods | 51.0 | 7 | §4.7.23 |
| RuntimeVisibleTypeAnnotations | 52.0 | 8 | §4.7.20 |
| RuntimeInvisibleTypeAnnotations | 52.0 | 8 | §4.7.21 |
| MethodParameters | 52.0 | 8 | §4.7.24 |
| Module | 53.0 | 9 | §4.7.25 |
| ModulePackages | 53.0 | 9 | §4.7.26 |
| ModuleMainClass | 53.0 | 9 | §4.7.27 |
| NestHost | 55.0 | 11 | §4.7.28 |
| NestMembers | 55.0 | 11 | §4.7.29 |
| Record | 60.0 | 16 | §4.7.30 |
| PermittedSubclasses | 61.0 | 17 | §4.7.31 |
表4.7-C. 预定义的类文件属性(按位置排序)
| 属性 | 位置 | 类文件版本 |
|---|---|---|
| SourceFile | ClassFile | 45.3 |
| InnerClasses | ClassFile | 45.3 |
| EnclosingMethod | ClassFile | 49.0 |
| SourceDebugExtension | ClassFile | 49.0 |
| BootstrapMethods | ClassFile | 51.0 |
| Module, ModulePackages, ModuleMainClass | ClassFile | 53.0 |
| NestHost, NestMembers | ClassFile | 55.0 |
| Record | ClassFile | 60.0 |
| PermittedSubclasses | ClassFile | 61.0 |
| ConstantValue | field_info | 45.3 |
| Code | method_info | 45.3 |
| Exceptions | method_info | 45.3 |
| RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations | method_info | 49.0 |
| AnnotationDefault | method_info | 49.0 |
| MethodParameters | method_info | 52.0 |
表4.7-C (续). 预定义的类文件属性(按位置排序)
| 属性 | 位置 | 类文件版本 |
|---|---|---|
| Synthetic | ClassFile, field_info, method_info | 45.3 |
| Deprecated | ClassFile, field_info, method_info | 45.3 |
| Signature | ClassFile, field_info, method_info, record_component_info | 49.0 |
| RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations | ClassFile, field_info, method_info, record_component_info | 49.0 |
| LineNumberTable | Code | 45.3 |
| LocalVariableTable | Code | 45.3 |
| LocalVariableTypeTable | Code | 49.0 |
| StackMapTable | Code | 50.0 |
| RuntimeVisibleTypeAnnotations, RuntimeInvisibleTypeAnnotations | ClassFile, field_info, method_info, Code, record_component_info | 52.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翻译