class文件是一组以8位字节为基础单位的二进制流组成的。在这个二进制流中没有任何分隔符,所有的数据项都是一个挨一个紧凑排列的,这就代表着其中每个字节代表什么含义,长度是多少,先后顺序如何,都是固定的
class文件头4个字节即为魔数。
大部分的文件都会使用魔数来进行文件识别,比如一般我们看到gif、jpeg等格式的文件就知道这是个图片。但是呢,程序识别文件类型却不是根据文件扩展名而是根据魔数来的。class文件的魔数是0xCAFEBABE,Java虚拟机判断一个文件是否是class文件就是依靠此魔数进行的。
接下来的4个字节是class文件版本号,其中前两个字节表示的是次版本号,后两个字节表示的是主版本号。
java虚拟机可以运行低于当前版本的class文件,但不能运行高于其版本的class文件。
常量池中主要存放两大类常量:
由于常量池中的常量数量是不确定的,所以紧接着版本号的两个字节用来代表常量池容量计数值(常量池索引从1开始)。
常量池后面两个字节代表访问标志,在访问标志中一共有32个标志位可用,现在定义出的标志位有一下8个:
类索引占两个字节,指向常量池中的CONSTANT_Class_info类型的常量,这个类型的常量中包含一个指向全限定名常量项的索引。
同类索引
因为一个类可以实现多个接口,故接口索引开始两个字节用来表示接口的数量,之后的每两个字节表示一个接口索引,用法同类索引与父类索引。
字段用于描述接口或者类中声明的变量,包括类变量和实例变量,但不包括局部变量
字段的开始两个字节表示字段数量,接下来就是字段的相关描述信息:
同字段
对于每个属性的结构,没有特别严格的要求,并且可以自定义属性信息,jvm运行时会忽略不认识的属性。
其中前两个字节为指向常量池中的CONSTANT_Utf8_info类型的属性名称,之后4个字节表示属性值所占用的位数,最后就是具体属性了。