深入理解Java虚拟机:第六章(一)类文件结构

Class文件的结构

class文件伪结构中有两种数据类型:

  • 无符号数
class文件图
class文件图

魔数magic

占4个字节,作用是确定文件是否能被虚拟机接受

版本号

包括次版本号和主版本号

常量池

存放两大常量:

  • 字面量
    • 如文本字符串、final常量
  • 符号引用
    • 开放的包、全限定名、方法名称和描述、句柄、类型、动态调用点等

常量池项目类型:

常量池项目类型
常量池项目类型

P221参照表,后面分析的内容要用到

访问标志

access_flag占两个字节,用于识别一些类或者接口层次的访问信息,例如是否定义为public、abstract、final类型

各个值得含义如下图:

访问标志.jpg
访问标志.jpg

没有使用到的标志位一律为0

类索引、父类索引与接口索引集合

类索引:确定类的全限定名

父类索引:确定类的父类的全限定名,只有一个。除了java.lang.Object外,所有Java类的父类索引都不为0

接口索引:集合就用来描述这个类实现了哪些接口

字段表集合

用于描述接口或类中声明的变量

字段表结构如下图

字段表结构.jpg
字段表结构.jpg

字段访问标志如下图

字段访问标志.jpg
字段访问标志.jpg

由于java语法原因,有些标志位不能同时选择。

字段表后面两项是name_indexdescriptor_indexx。分别代表字段的简单名称和方法描述符

方法表集合

方法表结构

方法表结构.jpg
方法表结构.jpg

方法访问标志与属性访问标志类似。只是增加和减少了部分属性。而方法中代码存放在方法属性表集合中一个名为“Code”的属性里面,属性表作为Class文件格式中最具扩展性的一种数据项目。

在java代码层面上,重载一个方法必须拥有一个与原方法不同的特征签名(特征签名是指一个方法中各个参数在常量池中的字段符号),该特征签名只包括方法名称、参数类型和顺序。

而在字节码层面上,特征签名还包括方法返回值和受检查异常表,因此,如果两个方法有相同的名称和特征签
名,但返回值不同,那么也是可以合法共存于同一个Class文件中的

属性表集合

属性表结构

属性表结构.jpg
属性表结构.jpg

code属性

方法体里的代码编译后会存储在字节码的code属性内,code属性出现在方法表里的属性集合之中,但接口或抽象类的方法就不存在code属性。

code属性表结构.jpg
code属性表结构.jpg
  • attribute_name_index:属性名称索引,CONSTRANT_Utf8_info型常量索引
  • attribute_length:属性值长度。属性名称索引和该值长度共6个字节
  • max_stack:操作数栈深度最大值,在方法执行时操作数栈不会超过这个深度。虚拟机根据这个值分配栈帧中操作栈的深度。
  • max_locals:局部变量表所需的存储空间,单位是槽。长度不超过32位的局部变量用一个槽存储,64位的用2个槽。变量槽是可以进行复用的。
  • code_length:字节码长度。理论值可以达到2的32次幂,但实际上不能超过u2长度,否则编译器拒绝编译。
  • code:存储字节码指令的一些列字节流

Exceptions属性

作用是列举出方法中可能抛出的受查异常

LineNumberTable属性

用于描述Java源码行号与字节码行号(字节码的偏移量)之间的对应关系。
它并不是运行时必需的属性

其他属性

  • LocalV ariableTable属性用于描述栈帧中局部变量表的变量与Java源码中定义的变量之间的关系。
  • LocalV ariableTypeTable。这个新增的属性结构与LocalVariableTable非常相似,仅仅是把记录的字段描述符的descriptor_index替换成了字段的特征签名,用于准确描述泛型类型。

  • SourceFile属性用于记录生成这个Class文件的源码文件名称,可选。

  • SourceDebugExtension属性用于存储额外的代码调试信息,例如定位JSP的信息。

  • ConstantV alue属性的作用是通知虚拟机自动为静态变量赋值。

  • InnerClasses属性用于记录内部类与宿主类之间的关联。

  • Deprecated属性用于表示某个类、字段或者方法,已经被程序作者定为不再推荐使用。

  • Synthetic属性代表此字段或者方法并不是由Java源码直接产生的,而是由编译器自行添加的。

  • StackMapTable:

  • Sign:ature:记录泛型签名信息

  • BootstrapMethods:

  • MethodParameters:记录方法的各个形参名称和信息,jdk8新增的

  • 模块化相关属性

    • exports:每一元素都代表一个被模块所导出的包
    • export_to_count:导出包的限定器,为0则无限定,否则后面跟着的export_to_index是以计数器值为长度的数组,只有在这个数组范围内的模块才允许被访问。
  • 运行期注解相关属性: