.java > .class > JVM

背景

实现语言无关性的基础仍然是虚拟机字节码存储格式

Java虚拟机只和Class二进制文件关联,Class文件中包含了Java虚拟机指令集符号表以及若干其它辅助信息

Java语言中的各种变量、关键字和运算符号的语义最终都是由多条字节码命令组合而成的,因此字节码命令所能提供的语义描述肯定会比Java语言本身更加强大。因此,有一些Java语言本身无法有效支持的语言特性不代表字节码本身无法有效支持,这也为其他语言实现一些有别于Java的语言特性提供了基础。

结构

任何一个Class文件都对应着唯一一个类或接口的定义信息,但反过来说,类或接口并不一定都得定义在文件里(也可以通过类加载器直接生成)。

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列,中间没有任何分隔符,Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8个字节进行存储。

大端模式(Big-endian),是指数据的高字节,保存在内存的低地址中,而数据的低字节,保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;

小端模式(Little-endian), 是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内在的低地址中,这种存储模式将地址的高低和数据位 权有效结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致;

Java虚拟机规范规定:Class文件个是采用一种类似于C语言结构体的伪结构来存储数据,结构体中只有两种数据:无符号数

无符号数

  • 基本的数据类型
  • u1:1个字节;u2:2个字节;u4:4个字节;u8:8个字节
  • 描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值

  • 多个无符号数或者其他表作为数据项构成的复合数据类型
  • 惯例以_info结尾
  • 用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表

格式

类型 名称 含义 数量
u4 magic 魔数 1
u2 minor_version Class文件的小版本 1
u2 major_version Class文件的主版本 1
u2 constant_pool_count 常量池数量 1
cp_info constant_pool 常量池 constant_pool_count-1
u2 access_flags 访问标志 1
u2 this_class 类索引集合 1
u2 super_class 父类索引集合 1
u2 interfaces_count 接口索引集合数量 1
u2 interfaces 接口索引集合 interfaces_count
u2 fields_count 字段表集合数量 1
field_info fields 字段表集合 fields_count
u2 methods_count 方法表集合数量 1
mthod_info methods 方法表集合 methods_count
u2 attributes_count 属性表集合数量 1
u2 attributes 属性表集合 attributes_count

无论是无符号数还是表,当需要描述同一类型单数量不定的多个数据时,经常会使用一个前置的容量计数器若干个连续的数据项的形式,这时称这一系列连续的某一类型的数据位某一类型的集合。

由于没有分隔符,所以Class文件中的内容(上表)的顺序或者数量,甚至是数据存储的字节序(Byte Ordering,Class文件中字节序位Big-Endiam),哪个字节代表的含义、长度、先后顺序,都是被严格限定的,都不可以改变。

详细介绍

  • 魔数、版本、常量池

  • 访问标志

  • 类索引、父类索引与接口索引集合
  • 字段表集合
  • 方法表集合
  • 属性表集合

参考资料

JVM Specification-1.7