JVM之Class文件的组成结构

Class 文件的组成结构

当你用16进制编译器打开一个java文件,你就能够看到相似这个的Java文件的模板。 java

什么是class文件?

Class 文件是一组以 8 位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在 Class 文件中,中间没有任何分隔符。Java 虚拟机规范规定 Class 文件采用一种相似 C 语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表,咱们以后也主要对这两种类型的数据类型进行解析。程序员

  • 无符号数: 无符号数属于基本数据类型,以 u一、u二、u四、u8 分别表明 1 个字节、2 个字节、4 个字节和 8 个字节的无符号数,能够用它来描述数字、索引引用、数量值或 utf-8 编码的字符串值。
  • 表: 表是由多个无符号数或其余表为数据项构成的复合数据类型,名称上都以 _info 结尾。

JAVA程序员的浪漫

Class 文件的头 8 个字节是魔数(magic number )和版本号,其中头 4 个字节是魔数,也就是 0xCAFEBABE,它能够用来肯定这个文件是否为一个能被虚拟机接受的 Class 文件(这经过扩展名来识别文件类型要安全,毕竟扩展名是能够随便修改的)。

后 4 个字节则是当前 Class 文件的版本号,其中第 五、6 个字节是次版本号,第 七、8 个字节是主版本号。安全

网上摘取一篇讲述CAFEBABE的小故事关于CAFEBABE:

常量池

从第 9 个字节开始,就是常量池的入口,常量池是 Class 文件中:编码

  • 与其余项目关联最多的的数据类型;
  • 占用 Class 文件空间最大的数据项目;
  • Class 文件中第一个出现的表类型数据项目。

常量池的开始的两个字节,也就是第 九、10 个字节,放置一个 u2 类型的数据,标识常量池中常量的数量 cpc (constant_pool_count),这个计数值有一个十分特殊的地方,就是它是从 1 开始而不是从 0 开始的,也就是说若是 cpc = 22,那么表明常量池中有 21 项常量,索引值为 1 ~ 21,第 0 项常量被空出来,为了知足后面某些指向常量池的索引值的数据在特定状况下须要表达“不引用任何一个常量池项目”时,将让这个索引值指向 0 便可。spa

常量池中记录的是代码出现过的全部 token(类名,成员变量名等,也是咱们接下来要修改的地方)以及符号引用(方法引用,成员变量引用等),主要包括如下两大类常量:3d

  • 字面量: 接近于 Java 语言层面的常量概念,包括
    • 文本字符串
    • 声明为 final 的常量值
  • 符号引用: 以一组符号来描述所引用的目标,包括
    • 类和接口的全限定名
    • 字段的名称和描述符
    • 方法的名称和描述符

常量池中的每一项常量都经过一个表来存储。目前一共有 14 种常量,不过麻烦的地方就在于,这 14 种常量类型每一种都有本身的结构,咱们在这里只详细介绍两种:CONSTANT_Class_info 和 CONSTANT_Utf8_info。code

CONSTANT_Class_info 的存储结构为:cdn

... [ tag=7 ] [ name_index ] ...
... [  1位  ] [     2位    ] ...
复制代码

其中,tag 是标志位,用来区分常量类型的,tag = 7 就表示接下来的这个表是一个 CONSTANT_Class_info,name_index 是一个索引值,指向常量池中的一个 CONSTANT_Utf8_info 类型的常量所在的索引值,CONSTANT_Utf8_info 类型常量通常被用来描述类的全限定名、方法名和字段名。它的存储结构以下:blog

... [ tag=1 ] [ 当前常量的长度 len ] [ 常量的符号引用的字符串值 ] ...
... [  1位  ] [        2位        ] [         len位         ] ...
复制代码
相关文章
相关标签/搜索