类文件结构

这一章节主要讲述了class数据结构的规范以及一些细节,不可避免的十分枯燥,但这部分也是jvm运行的重要基础,是深入了解jvm不可不接触的知识。

无关性的基石

class字节码实现平台无关性甚至语言无关性(包括除了java之外能运行在jvm上的语言:Clojure、Groovy、JRuby、Jython等)的基石,是一种字节码的存储格式,jvm不与包括Java在内的任何语言绑定,只与Class文件这种特定的二进制文件格式所关联,其中包含了jvm指令集、符号表以及若干其他辅助信息。

即jvm从不关心Class文件来源自何种语言。

Class类文件结构

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑排列,无任何分隔符。

Class文件采用一种类似C语言结构体的数据结构来存储数据,这种结构体中只有2中数据类型:无符号数和表。

  1. 魔数(Magic Number)与Class文件版本(Minor Version/Major Version)

    每个Class文件头4个字节称为魔数(Magic Number),确定这个文件是否是Class文件,固定为0xCAFEBABE。

    紧跟着魔数的4个字节存储了Class的版本号,JDK能向下兼容旧版本的Class文件,但不能向上兼容。

  2. 常量池(Constant Pool)

    Class文件的资源仓库,与其他项目关联最多的数据类型。

    前置了u2类型的常量池容量计数器(constant_pool_count),很奇葩,从1开始。

    常量分为两大类:

    • 字面量(Literal)

      类似于Java语言的常量,如文本字符串、final值等。

    • 符号引用(Symbolic References)

      • 类和接口的全限定名(Fully Qualified Name)
      • 字段的名称和描述符(Descriptor)
      • 方法的名称和描述符
  3. 访问标志(access_flags)

    是Class类还是接口,是否public,是否abstract,是否final等。

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

    都是u2类型,各自指向CONSTANT_Class_info的类描述符常量,确定了这个类的全限定名、父类的全限定名,接口的全限定名集合。

  5. 字段表集合

    描述接口或类中声明的变量,但不包括方法内部的局部变量。用一些修饰符(ACC_PUBLIC, ACC_STATIC, ACC_TRANSIENT等)的布尔值和常量池中的字段名、字段类型描述。

  6. 方法表集合

    与字段表集合类似。

    方法里面的Java代码,经过编译成字节码指令后,存在在方法属性表的一个名为Code的属性中。

    编译器可能会自动添加一些方法,如类构造器和实例构造器

  7. 属性表集合

    1. Code属性
    2. Exception属性
    3. LineNumberTable属性

      描述Java源代码与字节码行号之间的对应关系,用以在出错时借此显示出错行号,调试时根据源代码设置断点。

    4. LocalVariableTable

      描述栈帧中局部变量表中的变量与Java源码中定义的变量之间的关系,不是运行时必需。

      如果禁用,方法参数名会消失,显示arg0,arg1等占位符,断点调试时也无法根据参数名从上下文中获得参数值。

    5. SourceFile属性

    6. ConstantValue属性
    7. InnerClasses属性
    8. Deprecated/Synthetic属性
    9. StackMapTable属性
    10. Signature属性(泛型签名信息)
    11. BootstrapMethods属性

字节码指令简介

  1. 字节码与数据类型

    很多运算类型都是先转换成相应的运算类型再进行操作,以减少指令数量。

  2. 加载和存储指令

  3. 运算指令
  4. 类型转换指令
  5. 对象创建与访问指令
  6. 操作数栈管理指令
  7. 控制转移指令
  8. 方法调用和返回指令
  9. 异常处理指令
  10. 同步指令

公有设计与私有实现

公有设计:Java虚拟机规范

私有实现:Java虚拟机实现

私有实现必须能够读取Class文件并精确实现包含在其中的jvm代码的语义,与此同时,一个优秀的虚拟机实现,在必须的满足虚拟机规范约束下,对具体实现做出修改和优化。

这也是软件世界乃至所有行业制定标准者对实现标准者的约束,与实现者对制定者的反推动的经典模型。