深入理解JVM(六)——类文件结构

Java诞生之初就有的口号,Write Once,Run Anywhere

Java规范分为Java语言规范和Java虚拟机规范,Java实现平台无关性的基础是虚拟机和字节码存储格式,Java虚拟机不与包括Java在内的任何语言绑定,它只与Class文件这种特定的二进制文件格式关联

时至今日,已经有很多语言运行在Java虚拟机之上,包括Groovy,JRuby,Jython,Scala等,只要他们通过编译器,得到虚拟机可以识别的Class文件,那么就可以在虚拟机上运行。

Class类文件的结构

任何一个Class文件都对应唯一的一个类或者接口的定义信息,反之不然,类和接口不一定定义在文件里(可以通过Classloader生成)。

Class文件是一组以8Byte为基础单位的二进制流(高位在前分割)

Java虚拟机规定,Class文件格式采用类似C语言的伪结构来存储数据,只有两种数据类型,无符号数和表

无符号数

无符号数属于基本数据类型,如

无符号数 含义
u1 1个字节
u2 2个字节
u4 4个字节
u8 8个字节

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

类型 名称 数量 说明
u4 magic 1 魔数,头4个字节,确定这个Class文件是否能被虚拟机接受,值为0xCAFEBABE,出于安全不用文件名后缀而用魔数
u2 minor_version 1 5-6字节,次版本号,JDK版本向下兼容,JDK版本从45(1.1)开始,以后每个大版本发布,主版本号加1,如JDK1.6是50,最新的1.7生成的Class最大值为51
u2 major_version 1 7-8字节,主版本号,同上
u2 constant_pool_count 1 常量池入口,从1开始计算(其它均从0开始),代表常量池中有多少项常量,
cp_info constant_pool constant_pool_count-1 常量池,字面量(文本字符串,final常量值等)和符号引用(类和接口的全限定名,字段的名称和描述符,方法的名称和描述符),常量池中的 每一项常量都是一个表,JDK1.7之前有11种表结构,之后有14种;详细见下节
u2 access_flag 1 访问标志,表示这个是类还是接口,是否为public,是否为abstract,是否为final等
u2 this_class 1 该列的全限定名
u2 super_class 1 父类的全限定名
u2 interfaces_count 1 接口计数器
u2 interfaces interfaces_count 接口索引表
u2 fileds_count 1 字段计数器,接口或类中声明的变量
filed_info fileds fileds_count 字段表
u2 methods_count 1
method_info methods methods_count
u2 attributes_count 1
attribute_info attributes attributes_count

常量池的项目类型有

标志 描述
1 UTF-8编码的字符串
3 整型字面量
4 浮点型字面量
5 长整型字面
6 双精度浮点型字面量
7 类或接口的符号引用
8 字符串类型字面量
9 字段的符号引用
10 类中方法的符号引用
11 接口中方法的符号引用
12 字段或方法的部分符号引用
15 表示方法句柄
16 标志方法类型
18 表示一个动态方法调用点

可以通过javap工具的-verbose参数输出字节码内容,可以观察到引用常量池中的常量

猜你喜欢

转载自blog.csdn.net/rickey17/article/details/74141029