您的位置 首页 java

Java技术-JVM研究系列(2)Class文件分析和研究

承接上篇:

字段表集合

fields_count 字段计数器

fields_count 的值表示当前 Class 文件 fields[]数组的成员个数。 fields[]数组中每一项都是一个 field_info 结构的数据项,它用于表示该类或接口声明的类字段或者实例字段。

field_info 结构格式如下:

Java技术-JVM研究系列(2)Class文件分析和研究

属性集合

attributes_count 属性计数器

attributes_count 的值表示当前 Class 文件 attributes 表的成员个 数。attributes 表中每一项都是一个 attribute_info 结构的数据项。

attributes[]属性表

属性表,attributes 表的每个项的值必须是 attribute_info 结构(§4.7)。

属性(Attributes)在 Class 文件格式中的 ClassFile 结构、field_info 结构,method_info 结构和 Code_attribute 结构都有使用,所有属性的通用格式如下:

Java技术-JVM研究系列(2)Class文件分析和研究

对于任意属性,attribute_name_index 必须是对当前 Class 文件的常量池的有效16 位无符号 索引 。常量池在该索引处的项必须是 CONSTANT_Utf8_info 结构,表示当前属性的名字。attribute_length 项的值给出了跟随其后的字节的长度,这个长度不包括 attribute_name_index 和 attribute_name_index 项的 6 个字节。

有些属性因 Class 文件格式规范所需,已被预先定义好。这些属性在表 4.6 中列出,同时,被列出的信息还包括它们首次出现的Class文件版本和 Java SE 版本号。在本规范定义的环境 中,也就是已包含这些预定义属性的 Class 文件中,它们的属性名称被保留,不能再被属性表中其他的自定义属性所使用。 下表是 class 文件的属性:

方法表集合

在字段表后的 2 个字节是一个方法计数器,表示类中总有有几个方法,在字段计数器后,才是具体的方法数据。这里数据为:0002 。

methods_count 方法计数器

methods[] 数组中的每个成员都必须是一个 method_info 结构的 数据项,用于表示当前类或接口中某个方法的完整描述。如果某个 method_info 结构 的 access_flags 项既没有设置 ACC_NATIVE 标志也没有设置 ACC_ABSTRACT 标志, 那么它所对应的方法体就应当可以被 Java 虚拟机直接从当前类加载,而不需要引用其它 类。method_info 结构可以表示类和接口中定义的所有方法,包括实例方法、类方法、 实例初始化方法方法和类或接口初始化方法方法。methods[]数组 只描述当前类或接口中声明的方法,不包括从父类或父接口继承的方法。

Java技术-JVM研究系列(2)Class文件分析和研究

Log 类的字节码文件中,方法计数器的值为 00 02,表示一共有 2 个方法。

第一个方法:

0001 000700 0800 0100 0900 0000 1d00 0100 0100 0000 052a b700 01b1 0000 0001 000a 0000 0006 0001 0000 0003

  • 方法计数器后 2 个字节表示方法访问标识,这里是 0001,表示其实 ACC_PUBLIC 标识,对比上面的图表可知其表示 public 访问标识。
  • 紧接着 2 个字节表示方法名称的索引,这里是 00 07 表示指向了常量池第 7 个常量,查阅可知其指向了<init>。
  • 紧接着的 2 个字节表示方法描述符索引项,这里是 00 08 表示指向了常量池第 8 个常量,查阅可知其指向了()V。
  • 紧接着 2 个字节表示属性表计数器,这里是 00 01 表示该方法的属性表一共有 1 个属性。属性表的表结构如下:
Java技术-JVM研究系列(2)Class文件分析和研究

前两个字节是名字索引、接着 4 个字节是属性长度、接着是属性的值。这里前两个字节为 0009,指向了常量池第 9 个常量,查询可知其值为 Code,说明此属性是方法的字节码描述。


Code 属性是一个变长属性,位于method_info结构的属性表。一个 Code 属性只为唯一一个方法、实例类初始化方法或类初始化方法保存 Java 虚拟机指令及相关辅助信息。** 所有 Java 虚拟机实现都必须能够识别 Code 属性。如果方法被声明为 native 或者 abstract 类型,那么对应的 method_info 结构不能有明确的 Code 属性,其它情况下, method_info 有必须有明确的 Code 属性。**

Code 属性的格式如下:

Java技术-JVM研究系列(2)Class文件分析和研究

  • 根据 Code 属性对应表结构知道,前 2 个字节为 0009,即常量池第 9 个常量,查询知道是字符串常量 Code。
  • 接着 4 个字节表示属性长度,这里值为 0000 001d,即 29 的长度。下面我们继续分析 Code 属性的数据内容。
  • 紧接着 2 个字节为 max_stack 属性。这里数据为 00 01,表示操作数栈深度的最大值。
  • 紧接着 2 个字节为 max_locals 属性。这里是数据为 00 01,表示 局部变量 表所需的存储空间为 1 个 Slot。在这里 max_locals 的单位是 Slot,Slot 是虚拟机为局部变量分配内存所使用的最小单位。
  • 接着 4 个字节为 code_length,表示生成字节码这里给的长度。
  • 这里数据为 00 00 00 05,表示生成字节码长度为 5 个字节。

那么紧接着 5 个自己就是对应的数据,这里数据为 2a b7 00 01 b1,这一串数据其实就是字节码指令。通过查询字节码指令表,可知其对应的字节码指令:


读入 2A,查表得 0x2A 对应的指令为 aload_0,这个指令的含义是将第 0 个 Slot 中为 reference 类型的本地变量推送到操作数栈顶。


读入 B7,查表得0xB7对应的指令为 invokespecial,这条指令的作用是以栈顶的 reference 类型的数据所指向的对象作为方法接收者,调用此对象的实例 构造器 方法、private 方法或者它的父类的方法。这个方法有一个 u2 类型的参数说明具体调用哪一个方法,它指向常量池中的一个 CONSTANT_Methodref_info 类型常量,即此方法的方法符号引用。

读入 00 01,这是 invokespecial 的参数,查常量池得 0x0001 对应的常量为实例构造器“”方法的符号引用。

读入 B1,查表得0xB1对应的指令为 return,含义是返回此方法,并且返回值为void。这条指令执行后,当前方法结束。

着 2 个字节为异常表长度,这里数据为 00 00,表示没有异常表数据。那么接下来也就不会有异常表的值。

紧接着 2 个字节是属性表的长度,这里数据为 00 01,表示有一个属性。该属性长度为一个 attribute_info 那么长。

首先,前两个字节表示属性名称索引,这里数据为:00 0A。指向了第 10 个常量,查阅可知值为:LineNumberTable。

LineNumberTable 属性是可选变长属性,位于 Code(§4.7.3)结构的属性表。它被调试 器用于确定 源文件 中行号表示的内容在 Java 虚拟机的 code[]数组中对应的部分。在 Code 属性 的属性表中, LineNumberTable 属性可以按照任意顺序出现,此外,多个 LineNumberTable 属性可以共同表示一个行号在源文件中表示的内容,即 LineNumberTable 属性不需要与源文件 得行一一对应。

LineNumberTable 属性格式如下:

Java技术-JVM研究系列(2)Class文件分析和研究

其前两个字节是属性名称索引,就是上面已经分析过的 00 0A。

接着 4 个字节是属性长度,这里数据为 00 00 00 06,表示有 6 个字节的数据。接着 2 个字节是 LineNumberTable 的长度,这里数据是 00 01,表示长度为 1。接着跟着 1 个 line_number_info 类型的数据,下面是 line_number_info 表的结构,其包含了 start_pc 和 line_number 两个 u2 类型的数据项。前者是字节码行号,后者是 Java 源码行号。

那么接下来 2 个字节为 00 00,即 start_pc 表示的字节码行号为第 0 行。接着 00 03,即 line_number 表示 Java 源码行号为第 3 行。

从上面的 反编译 来看,上面的分析也是对的:

第二个方法这里就不详细分析了,大家可以自己对着上面的反编译结果进行分析。 第二个方法开头是 0009,表示的是 ACC_PUBLIC 与 ACC_STATIC 合在一起的结果。

文章来源:智云一二三科技

文章标题:Java技术-JVM研究系列(2)Class文件分析和研究

文章地址:https://www.zhihuclub.com/183682.shtml

关于作者: 智云科技

热门文章

网站地图