.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),哪个字节代表的含义、长度、先后顺序,都是被严格限定的,都不可以改变。
详细介绍
访问标志
- 类索引、父类索引与接口索引集合
- 字段表集合
- 方法表集合
- 属性表集合