欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA字节码文件之第四篇(方法分析)

程序员文章站 2022-06-22 10:54:03
LineNumberTable 属性表存放方法的行号信息 ;属于调试信息,不是运行时必需的。在使用javac编译器编译Java程序时,默认会在class文件中生成这些信息。可以使用javac提供的-g:none选项来关闭该信息的生成 ......

一、methods 方法字节码结构

methods 字节码结构:

methods num:占两byte,methods 的具体内存占n个byte

JAVA字节码文件之第四篇(方法分析)

方法中每个属性都是attribute_info,attribute_info的结构:

JAVA字节码文件之第四篇(方法分析)

1、attribute_name_index:属性名的索引
2、attribute_length:表示attribute所包含的字节数,不包含attribute_name_index和attribute_length字段
3、max_stack:表示这个方法运行的任何时刻所能到达的操作数栈的最大深度。
4、max_locals:表示方法执行期间创建的局部变量的数目,包含用来表示传入的参数的局部变量。
5、code_length:表示该方法所包含的字节码的字节数以及具体的指令码,具体字节码即是该方法被调用时,虚拟机执行的字节码
6、code[code_length]:虚拟机运行时具体的字节
7、exception_table_length:异常表的长度
8、exception_table:

  • 这里存放的是处理异常的信息每个exception_table表项由start_pc, end_pc, handler_pc, catch_type组成;
  • start_pc 和end_pc表示在code数组中的从start_pc到end_pc处(包含start_pc,不包含end_pc)的指令抛出的异常会由这个表项来处理。
  • handler_pc表示处理异常的代码的开始处;
  • catch_type表示会被处理的异常类型,它指向常量池里的一个异常类。当catch_type为0时,表示处理所有的异常

9、attribute_count:
10、attribute_info attributes[attribute_count]

 二、methods 字节码分析

JAVA字节码文件之第四篇(方法分析)

上一节 java字节码文件之第三篇(访问标识) 我们分析到了 fields(属性)字节码 就是图中红色箭头的位置。

1、methods num(3) : 占两个byte 00 03,即该类有三个方法。

第一个方法:

access_flags(1):占2个byte 00 01;根据 上一节java字节码文件之第三篇(访问标识)  可知 

JAVA字节码文件之第四篇(方法分析)

 name_index(7):占 2个字节 00 07;索引为7,对应常量池中的#7, 由<init>可知他是一个构造方法

JAVA字节码文件之第四篇(方法分析)

 descriptor_index(8):占两个byte,00 08,对应常量池的#8,由()v可知这是一个无参数的(构造)方法

JAVA字节码文件之第四篇(方法分析)

attribute_info结构

attributes_count(1):占两个byte 00  01,表示该方法第一个属性(这里的属性并不是我们常说的类的属性,方法的参数,而是编译器生成的属性)

1、attribute_name_index(9):方法的第一个属性名字,占两个byte,对应常量池中的#9,code就是该方法的第一个属性

JAVA字节码文件之第四篇(方法分析)

2、attribute_length(0x38=56):占4个byte 00 00 00 38,表明该属性code的长度是56个字节。所以整个attribute_info 对应字节如下图

JAVA字节码文件之第四篇(方法分析)

3、max_stack(2):占2个byte 00 02  操作数栈的最大深度是2

4、max_locals(1):占两个byte 00 01   

5、code_length(10) :占四个字节 00 00 00 0a  ,

6、code[code_length]:占 code_length 个byte 即 10个byte ,2a b7 00 01 2a 04 b5 00 02 b1 ;表明该方法在执行时的具体指令;

JAVA字节码文件之第四篇(方法分析)

 这些十六进制指令怎么与 图片中的助记符关联的,参考该 网站 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n

例如:aload_0=2a

JAVA字节码文件之第四篇(方法分析)

invokespecial=b7 ,   之后的 00  01是他的参数,指向常量池中的#1

JAVA字节码文件之第四篇(方法分析)

JAVA字节码文件之第四篇(方法分析)

父类的构造方法

iconst_1=4

 JAVA字节码文件之第四篇(方法分析)

putfield=b5  ,后两个byte 是 参数  00 02,对应常量池的#2

JAVA字节码文件之第四篇(方法分析)

 JAVA字节码文件之第四篇(方法分析)

 就是给属性赋值 即 int num=1  

return = b1 ,构造方法返回void

JAVA字节码文件之第四篇(方法分析)

7、exception_table_length(0): 占两个byte 00  00   ,所以默认的构造器不抛出异常

8、exception_table_info:由于exception_table_length =0 ,所以该部分内容为空

9、attribute_count (2): 占两个byte 00 02 ,即构造器的code属性有两个扩展属性

10、attribute_info[attribute_count] : 00 0a ,0a=10 ,第一个扩展属性的索引=10,即常量池的#10 

JAVA字节码文件之第四篇(方法分析)

 11、linenumbertable 分析

attribute_length : 占4个byte,00 00 00 0a;0x0a=10,所以00 02 00 00 00 08 00 04 00 09 是linenumbertable 的具体指令;

JAVA字节码文件之第四篇(方法分析)

 前两个字节 00 02 表示 有两对映射关系,00 00 对应 00 08  ,08对应常量池的#8 ;00 04 对应 00 09 ,对应常量池的#9

12、第二个扩展属性 00 0b,0x0b=11 ,对应常量池的#11 

JAVA字节码文件之第四篇(方法分析)

 attribute_length :占四个字节 00 00 00 0c,对应的 localvariabletable 的内容是 12 个字节 ,即 00 01 00 00 00 0a 00 0c 00 0d 00 00 。

JAVA字节码文件之第四篇(方法分析)

局部变量的格式:00 01 

开始位置 00 00 

结束位置 00 0a(0a=10) 

索引是  00

局部变量对应常量池的位置0c(c=12) 

JAVA字节码文件之第四篇(方法分析)

 当前局部变量的描述00 0d ,对应常量池的#13

JAVA字节码文件之第四篇(方法分析)

 最后的00 00 是一个校验符,没有具体的逻辑含义。

至从第一个方法分析完毕。

三、linenumbertable

linenumbertable 属性表存放方法的行号信息 ;属于调试信息,不是运行时必需的。在使用javac编译器编译java程序时,默认会在class文件中生成这些信息。可以使用javac提供的-g:none选项来关闭该信息的生成

JAVA字节码文件之第四篇(方法分析)

四、localvariabletable:列出了所有栈帧中的局部变量

linenumbertable