字节码
魔数
字节码开头的4个字符(U4)表述魔数,魔数为固定值ca fe ba be
大小版本
Jdk版本如1.8.x,x就表示jdk的小版本,小版本是紧跟着魔数后的两个字节U2,大版本是紧跟在小版本后的两个字节U2,如1.8
16进制的34转化为10进制为52,对应java大版本为1.8
常量池
紧跟在版本后面的U2表示常量池数量,18表示有23个常量(24-1)
常量池后紧跟常量,每个常量开始都有一个U1,表示常量的类型,常量类型有如下几种:
以第一个常量为例子
0a表示类型为10(CONSTANT_Methodref)的常量,0004表示名称在常量池的索引,0014表示描述符在常量池的索引
访问修饰符
紧跟在常量池之后的是访问修饰符U2:
名称 |
字节码 |
含义 |
ACC_PUBLIC |
0x0001 |
公开 |
ACC_PRIVATE |
0x0002 |
私有 |
ACC_PROTECTED |
0x0004 |
protected |
ACC_STATIC |
0x0008 |
静态 |
ACC_FINAL |
0x0010 |
Final |
ACC_SYNCHRONIZED |
0x0020 |
同步 |
ACC_VOLATILE |
0x0040 |
volatile |
ACC_TRANSIENT |
0x0080 |
不需要序列化 |
ACC_NATIVE |
0x0100 |
native |
ACC_INTERFACE |
0x0200 |
接口 |
ACC_ABSTRACT |
0x0400 |
抽象 |
ACC_STRICT |
0x0800 |
strictfp |
ACC_SUPER |
0x0020 |
超类 |
表示ACC_PUBLIC+ ACC_SUPER公开的存在超类的
This_Class
访问修饰符之后的U2,表示this类在常量池中的索引
Supper_Class
This_Class之后的U2,表示supperClass在常量池中的索引
Interface-count
紧跟这supper_Class之后的U2,表示接口数量
表示存在1个接口,接口后的U2表示接口在常量池中的索引
Fields
接口之后的U2,表示属性数量
Fields池
属性之后紧跟属性池,属性池属性如下
访问修饰符
每个属性的一个U2表示属性修饰符
表示ACC_PRIVATE,私有的
属性名索引
访问修饰符之后的U2,表示属性名在常量池中的索引
属性描述符索引
属性名索引之后的U2表示属性描述符索引
Field_attributes_count
属性描述符之后的U2,表示Field_attributes_count
表示没有Field_attributes
methods_count
属性之后的U2,表示方法数量
表示存在三个方法
method_info
紧跟在方法数量后面的,是具体的方法信息
com.sun.org.apache.bcel.internal.Constants封装了相应的助记符信息
访问修饰符
每个方法信息的第一个U2,表示方法的访问修饰符
表示ACC_PUBLIC,公开的
方法名索引
紧跟在访问修饰符之后的U2,表示方法名在常量池中的索引
方法描述索引
紧跟在方法名索引后的U2,表示方法描述在常量池中的索引
attributes_count
紧跟在方法描述索引后的U2,表示attributes_count数量信息
表示attributes_count的数量为1
attributes_info
紧跟在attributes_count之后的是具体attribute信息
Code_attribute { //Code_attribute包含某个方法、实例初始化方法、类或接口初始化方法的Java虚拟机指令及相关辅助信息
u2 attribute_name_index; 0007 Code
u4 attribute_length; 0000002F 47
u2 max_stack; 0001 1 //用来给出当前方法的操作数栈在方法执行的任何时间点的最大深度
u2 max_locals; 0001 1 //用来给出分配在当前方法引用的局部变量表中的局部变量个数
u4 code_length; 00000005 5 //给出当前方法code[]数组的字节数
u1 code[code_length]; 2AB70008 B1 42、183、0、8、177
//给出了实现当前方法的Java虚拟机代码的实际字节内容 (这些数字代码实际对应一些Java虚拟机的指令)
u2 exception_table_lentgh; 0000 0 //异常的信息
{
u2 start_pc; //这两项的值表明了异常处理器在code[]中的有效范围,即异常处理器x应满足:start_pc≤x≤end_pc
u2 end_pc; //start_pc必须在code[]中取值,end_pc要么在code[]中取值,要么等于code_length的值
u2 handler_pc; //表示一个异常处理器的起点
u2 catch_type; //表示当前异常处理器需要捕捉的异常类型。为0,则都调用该异常处理器,可用来实现finally。
} exception_table[exception_table_lentgh]; 在本类中大括号里的结构为空
u2 attribute_count; 0002 2 表示该方法的其它附加属性,本类有1个
attribute_info attributes[attributes_count]; 000A、000B LineNumberTable、LocalVariableTable
}
attribute_name_index
每个attributes_info,的第一个U2,表示attributes_name_index
attribute_length
紧跟之后的U4来表示
表示后面的2*16+15=47个长度为attribute_length
max_stack
紧跟之后的U2,用来给出当前方法的操作数栈在方法执行的任何时间点的最大深度
当前方法的操作数栈在方法执行的任何时间点的最大深度为1
max_locals
紧跟之后的U2,用来给出分配在当前方法引用的局部变量表中的局部变量个数
当前方法引用的局部变量表中局部变量数量为1,为this
code_length
紧跟之后的U4,表示给出当前方法code[]数组的字节数
当前方法的code[]数组字节数为5
2a表示
B7表示invokespecial,0001,表示参数索引
B1表示return
exception_table_lentgh
{
u2 start_pc; //这两项的值表明了异常处理器在code[]中的有效范围,即异常处理器x应满足:start_pc≤x≤end_pc
u2 end_pc; //start_pc必须在code[]中取值,end_pc要么在code[]中取值,要么等于code_length的值
u2 handler_pc; //表示一个异常处理器的起点
u2 catch_type; //表示当前异常处理器需要捕捉的异常类型。为0,则都调用该异常处理器,可用来实现finally。
}异常表属性
紧跟之后的U2,表示异常表长度
表示没有异常信息
code_ attribute_count
紧跟其后的U2,表示code_attribute数量
表示存在两个属性信息
LineNumberTable和LocalVariableTable又是两个预定义的attribute,其结构如下:
LineNumberTable_attribute { //被调试器用来确定源文件中由给定的行号所表示的内容,对应于Java虚拟机code[]数组的哪部分
u2 attribute_name_index; 000A
u4 attribute_length; 00000006
u2 line_number_table_length; 0001
{ u2 start_pc; 0000
u2 line_number; 0004 //该值必须与源文件中对应的行号相匹配
} line_number_table[line_number_table_length];
}
以及:
LocalVariableTable_attribute {
u2 attribute_name_index; 000B
u4 attribute_length; 0000000C
u2 local_variable_table_length; 0001
{ u2 start_pc; 0000
u2 length; 0005
u2 name_index; 000C
u2 descriptor_index; 000D //用来表示源程序中局部变量类型的字段描述符
u2 index; 0000
} local_variable_table[local_variable_table_length];
然后就是第二个方法,具体略过。
attributes_count
紧跟之后的U2是file_attributes_count
表示有一个属性
attributes_info
SourceFile_attribute {
u2 attribute_name_index; 0017 SourceFile
u4 attribute_length; 00000002 2
u2 sourcefile_index; 0018 ByteCodeTest.java //表示本class文件是由ByteCodeTest.java编译来的
}
attribute_name_index
U2
0012表示fileAttribute名称索引
attribute_length
U4
sourcefile_index
U2