Java虚拟机class类文件结构

不写废话,帮助你快速理解应对面试

目录

class类文件的作用
class类文件的结构
1. 数据结构
2. class文件结构
魔数
版本
常量池
访问标志
类/父类/接口
字段描述集合
方法描述集合
属性描述集合

class类文件的作用

Java能够实现"一次编译,到处运行”,这其中class文件要占大部分功劳。为了让Java语言具有良好的跨平台能力,Java独具匠心的提供了一种可以在所有平台上都能使用的一种中间代码——字节码类文件(.class文件),同时也解除了 Java 虚拟机和 Java 语言之间的耦合。

class类文件的结构

数据结构

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件中,中间没有添加任何分隔符。Class文件中只有两种数据类型:无符号数和表

无符号数:属于基本的数据类型,有u1, u2, u4, u8,分别代表1个字节、2个字节、4个字节和8个字节的无符号数。

:表是由多个无符号数或者其他表作为数据项构成的复合数据类型,class文件中所有的表都以“_info”结尾。其实,整个 Class 文件本质上就是一张表。

class文件结构

在class文件中只存在无符号数和表这两种数据结构。这些结构按照预先规定好的顺序紧密的从前向后排列,相邻的项之间没有任何间隙。如下图所示:


class文件结构

当 JVM 加载某个 class 文件时,JVM 就是根据上图中的结构去解析 class 文件,加载 class 文件到内存中,并在内存中分配相应的空间。具体某一种结构需要占用大多空间,可以参考下图:


class文件结构详细表

魔数

魔数

在class文件开头的四个字节是class文件的魔数,它是一个固定的值——0XCAFEBABE。
魔数是class文件的标志,也就是说它是判断一个文件是不是class格式文件的标准。

版本

版本

紧跟在魔数后面的两个字节代表当前class文件的版本号。
前两个字节0000代表次版本号(minor_version),后两个字节0034是主版本号(major_version),对应的十进制值为 52,也就是说当前 class 文件的主版本号为 52,次版本号为 0。所以综合版本号是 52.0,也就是 jdk1.8.0

常量池

紧跟在版本号之后的是一个叫作常量池的表(cp_info)。
在常量池中保存了类的各种相关信息,比如类的名称、父类的名称、类中的方法名、参数名称、参数类型等,这些信息都是以各种表的形式保存在常量池中的。

常量池中的每一项常量都是一个表,不同的表是有不同的结构,下面是14种表的具体含义:

常量池中的表类型

举个例子:

比如第3行的开头是07是,那么就是对应CONSTANT_Class_info这个info,而CONSTANT_Class_info对应的是下面的数据结构:

表解释说明:
tag:占用一个字节大小。比如值为7,说明是CONSTANT_Class_info类型表。
name_index:是一个索引值,可以将它理解为一个指针,指向常量池中索引为 name_index 的常量表。比如 name_index = 2,则它指向常量池中第 2 个常量。

紧跟07 后面的11就是索引第11项常量的意思,第11项是01 0003 69 6e 63, 其中tag是01,也就是CONSTANT_utf8_info这个info,它的数据结构:


CONSTANT_utf8_info

所以,长度是3,往后数三个字节就是69 6e 63,对应的就是inc,这个也就是方法的名称。

访问标志

在常量池之后紧接这两个字节是访问标志,识别一些类或者接口层次的访问信息:


访问标志

类/父类/接口

在访问标志后分别是this_class/super_class/interfaces_count

0003 //this_class           确定这个类的全限定名
0004 //super_class          java.lang.Object该值就是0000
0000 //interfaces_count     该类没有实现任何接口,接口的索引表不占用任何字节

字段描述集合

对于 Java 类中的变量,也可以使用 public、private、final、static 等标识符进行标识。因此解析字段时,需要先判断它的访问标志,字段的访问标志如下所示:


字段访问标志

方法描述集合

方法表集合和字段表集合很类似,有一个区别就是用描述符描述方法时,需要先参数列表后返回值,


方法表结构

并且有自己的访问标志,具体如下:


访问标志

属性描述集合

属性表结构并没有一个固定的表结构,各种属性表只要满足以下结构就可以了:

属性表结构

你可能感兴趣的:(Java虚拟机class类文件结构)