Java虚拟机(十二)--字节码解析附录

JVM常量池元素


11种常量
编号 常量池元素名称 tag位标识 含义
1 CONSTANT_Utf8_info 1 utf-8编码的字符串
2 CONSTANT_Integer_info 3 整型字面量
3 CONSTANT_Float_info 4 浮点型字面量
4 CONSTANT_Long_info 5 长整型字面量
5 CONSTANT_Double_info 6 双精度字面量
6 CONSTANT_Class_info 7 类或接口的符号引用
7 CONSTANT_String_info 8 字符串类型字面量
8 CONSTANT_Fieldref_info 9 字段的符号引用
9 CONSTANT_Methodref_info 10 类中方法的符号引用
10 CONSTANT_InterfaceMethodref_info 11 接口中方法的符号引用
11 CONSTANT_NameAndType_info 12 字段和方法的名称以及类型的符号引用

常量池元素的复合结构
类型/含义 结构 类型 描述
CONSTANT_Utf8_info
UTF-8编码的字符串
tag u1 值为1
length u2 utf-8缩略编码字符串所占字节数
bytes u1 长度为length的utf-8编码字符串
CONSTANT_Integer_info
整型字面量
tag u1 值为3
bytes u4 按照高位在前存储的int值
CONSTANT_Float_info
浮点型字面量
tag u1 值为4
bytes u4 按照高位在前存储的float值
CONSTANT_Long_info
长整型字面量
tag u1 值为5
bytes u8 按照高位在前存储的long值
CONSTANT_Double_info
双精度浮点型字面量
tag u1 值为6
bytes u8 按照高位在前存储的double值
CONSTANT_Class_info
类或接口的符号引用
tag u1 值为7
index u2 指向全限定名常量项的索引
CONSTANT_String_info
字符串类型字面量
tag u1 值为8
index u2 指向字符串字面量的索引
CONSTANT_Fieldref_info
字段的符号引用
tag u1 值为9
index u2 指向CONSTANT_Class_info的索引
index u2 指向Constant_NameAndType_info的索引
CONSTANT_Methodref_info
类中方法的符号引用
tag u1 值为10
index u2 指向CONSTANT_Class_info的索引
index u2 指向Constant_NameAndType_info的索引
CONSTANT_InterfaceMethodref_info
接口中方法的符号引用
tag u1 值为11
index u2 指向CONSTANT_Class_info的索引
index u2 指向Constant_NameAndType_info的索引
CONSTANT_NameAndType_info
字段和方法的名称以及类型的符号引用
tag u1 值为12
index u2 指向字段或方法名称常量项的索引
index u2 指向字段或方法描述符常量项的索引

访问标识与继承信息

字节码文件中,紧跟着常量池信息之后的就是访问标志,access_flags结构,该结构类型是u2,占用2个字节空间。
access_flags标识代表访问标志位,该标志用于标注类或接口层次的访问信息,如当前class是类还是接口,是否是public等。

	access_flags可选项
标志名称 标识值 含义
ACC_PUBLIC 0x0001 是否是public
ACC_FINAL 0x0010 是否是final,只有类可以设置为这个值
ACC_SUPER 0x0020 是否允许使用invokespecial,jdk 1.2后这个值为真
ACC_INTERFACE 0x0200 标识这是一个接口
ACC_ABSTRACT 0x0400 是否是抽象类型,对于接口和抽象类为真,其他类为假
ACC_SYNTHETIC 0x1000 标识这个类不是由用户代码产生
ACC_ANNOTATION 0x2000 标识这是一个注解
ACC_ENUM 0x4000 标识这是一个枚举

public final class类的访问标志值是 0x0031,也就是ACC_PUBLIC,FINAL,SUPER的异或值。
public class类的访问标志值是 0x0021


fields结构组成

类型 名称 数量
u2 access_flags 1
u2 name_index 1
u2 descriptor_index 1
u2 attributes_count 1
attribute_info attributes attributes_count

access_flags的可选项

标识名称 标志值 含义
ACC_PUBLIC 0x0001 字段是否是public
ACC_PRIVATE 0x0002 字段是否是private
ACC_PROTECTED 0x0004 字段是否是protected
ACC_STATIC 0x0008 字段是否是static
ACC_FINAL 0x0010 字段是否是final
ACC_VOLATILE 0x0040 字段是否是volatile
ACC_TRANSIENT 0x0080 字段是否是transient
ACC_SYNTHETIC 0x1000 字段是否是编译器自动生成
ACC_ENUM 0x4000 字段是否是enum

字段描述符与基本数据类型对应表:

描述符 含义
B byte
C char
D double
F float
I int
J long
S short
Z boolean
V 特殊类型void
L 对象类型,比如Ljava/lang/Object

String[][],的描述符为[[Ljava/lang/String;


methods结构组成

类型 名称 数量
u2 access_flags 1
u2 name_index 1
u2 descriptor_index 1
u2 attributes_count 1
attribute_info attributes attributes_count

access_flags的可选项

标识名称 标志值 含义
ACC_PUBLIC 0x0001 字段是否是public
ACC_PRIVATE 0x0002 字段是否是private
ACC_PROTECTED 0x0004 字段是否是protected
ACC_STATIC 0x0008 字段是否是static
ACC_FINAL 0x0010 字段是否是final
ACC_SYNCHRONIZED 0x0020 字段是否是synchronized
ACC_BRIDGE 0x0040 方法是否由编译器产生的桥接方法
ACC_VARARGS 0x0080 方法是否接收可变参数
ACC_NATIVE 0x0100 方法是否是native
ACC_ABSTRACT 0x0400 方法是否abstract
ACC_STRICTFP 0x0800 方法是否strictfp
ACC_SYNTHETIC 0x1000 方法是否是编译器自动生成

9大属性表集合

属性名称 使用位置 含义
Code 方法表 含有字节码指令
ConstantValue 字段表 final关键字定义的常量值
Deprecated 类文件,字段表,方法表 被声明为deprecated的方法和字段
Exceptions 方法表 方法抛出的异常
InnerClassed 类文件 内部类列表
LineNumberTable Code属性 源码行号与字节码指令的对应关系
LocalVariableTable Code属性 方法局部变量的描述
SourceFile 类文件 源文件名称
Synthetic 类文件、字段表、方法表 方法或字段是否是编译器自动生成

Code属性(除了接口方法和抽象方法以外,都有)

类型 名称 数量
u2 attribute_name_index 1
u4 attribute_length 1
u2 max_stack 1
u2 max_locals 1
u4 code_length 1
u1 code code_length
u2 exception_table_length 1
exception_info exception_table exception_table_length
u2 atribute_count 1
attribute_info attributes atribute_count

code_length长度为u4,所以如果一个方法超过了65535条字节码指令,javac将拒绝编译。

ConstantValue属性

类型 名称 数量
u2 attribute_name_index 1
u4 attribute_length 1
u2 constantvalue_index 1

虚拟机规范要求,只有static修饰的字段才能有constantValue属性,但是编译器又加了个条件,必须同时被final和static修饰的字段才能有这个属性。
否则在< clinit>中初始化。

Exceptions属性
方法描述时throws关键字抛出的异常,与Code属性平级。

类型 名称 数量
u2 attribute_name_index 1
u4 attribute_length 1
u2 number_of_exceptions 1
u2 exception_index_table number_of_exceptions

InnerClass属性

类型 名称 数量
u2 attribute_name_index 1
u4 attribute_length 1
u2 numbers_of_classes 1
inner_classes_info inner_classed numbers_of_classes

inner_classes_info表结构

类型 名称 数量
u2 inner_classes_info_index 1
u2 outer_classes_info_index 1
u2 inner_name_index 1
u2 inner_name_access_flags 1

lineNumberTable

类型 名称 数量
u2 attribute_name_index 1
u4 attribute_length 1
u2 line_number_table_length 1
line_number_info line_number_table line_number_table_length

line_number_info

类型 名称 数量 说明
u2 start_pc 1 字节码行号
u2 line 1 java源码行号

localvariabletable属性
用于描述栈帧中局部变量表中的变量与Java源码中定义的变量之间的关系

类型 名称 数量
u2 attribute_name_index 1
u4 attribute_length 1
u2 local_variable_table_length 1
local_variable_info local_variable_table local_variable_table_length

local_variable_info的结构

类型 名称 数量 说明
u2 start_pc 1 局部变量的声明周期开始的字节码偏移量
u2 length 1 局部变量作用范围覆盖的长度
u2 name_index 1 变量名索引
u2 description_index 1 局部变量描述符索引
u2 index 1 局部变量在栈帧局部变量表中slot的位置

不生成该属性,则他人引用这个方法时,参数名称都将丢失,调试时调试器无法根据参数名称从运行上下文中获取参数值。

SourceFile属性

类型 名称 数量
u2 attribute_name_index 1
u4 attribute_length 1
u2 sourcefile_index 1

Deprecated和synthetic没有属性值,只存在有和没有的区别。

类型 名称 数量
u2 attribute_name_index 1
u4 attribute_length 1

attribute_length的值必须为0x0000 0000

猜你喜欢

转载自blog.csdn.net/ljz2016/article/details/82929504