Java中class文件结构

class文件是一组以8位字节为基础单位的二进制流组成的。在这个二进制流中没有任何分隔符,所有的数据项都是一个挨一个紧凑排列的,这就代表着其中每个字节代表什么含义,长度是多少,先后顺序如何,都是固定的

魔数

class文件头4个字节即为魔数。

大部分的文件都会使用魔数来进行文件识别,比如一般我们看到gif、jpeg等格式的文件就知道这是个图片。但是呢,程序识别文件类型却不是根据文件扩展名而是根据魔数来的。class文件的魔数是0xCAFEBABE,Java虚拟机判断一个文件是否是class文件就是依靠此魔数进行的。

版本号

接下来的4个字节是class文件版本号,其中前两个字节表示的是次版本号,后两个字节表示的是主版本号。

java虚拟机可以运行低于当前版本的class文件,但不能运行高于其版本的class文件。

常量池

常量池中主要存放两大类常量:

  • 字面量
    • 字符串
    • 被声明为final类型的常量
  • 符号引用
    • 类和接口的全限定名
    • 字段的名称和描述符
    • 方法的名称和描述符

由于常量池中的常量数量是不确定的,所以紧接着版本号的两个字节用来代表常量池容量计数值(常量池索引从1开始)。

访问标志

常量池后面两个字节代表访问标志,在访问标志中一共有32个标志位可用,现在定义出的标志位有一下8个:

没有使用的标志位和不符合条件的标志位一律为0

类索引

类索引占两个字节,指向常量池中的CONSTANT_Class_info类型的常量,这个类型的常量中包含一个指向全限定名常量项的索引。

父类索引

同类索引

接口索引

因为一个类可以实现多个接口,故接口索引开始两个字节用来表示接口的数量,之后的每两个字节表示一个接口索引,用法同类索引与父类索引。

字段

字段用于描述接口或者类中声明的变量,包括类变量和实例变量,但不包括局部变量

字段的开始两个字节表示字段数量,接下来就是字段的相关描述信息:

  • 访问标志
  • 名称
  • 描述符
  • 属性表的数量
  • 属性表

方法

同字段

属性

对于每个属性的结构,没有特别严格的要求,并且可以自定义属性信息,jvm运行时会忽略不认识的属性。

其中前两个字节为指向常量池中的CONSTANT_Utf8_info类型的属性名称,之后4个字节表示属性值所占用的位数,最后就是具体属性了。

原文发布于微信公众号 - Java学习录(Javaxuexilu)

原文发表时间:2019-05-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券