java语言能很好地保持向后兼容,class文件结构的稳定性功不可没,下面来介绍class文件的结构
class文件是一组以8字节为基础单位的二进制流,各个数据项严格按照顺序紧凑的排列在文件中,中间没有添加任何分隔符。当遇到需要占用8个字节以上空间的数据项时,则会按照高位在前的方式分割 成若干个8个字节进行存储。
《java虚拟机规范》中规定,Class文件采用类似于C语言结构体的伪结构来存储数据,这种伪结构只有两种数据类型:“无符号数”,“表”。
Class的结构不像XML等描述语言,由于它没有任何分隔符 号,所以在表中的数据项,无论是顺序还是数量,甚至于数据存储的字节序(Byte Ordering,Class 文件中字节序为Big-Endian)这样的细节,都是被严格限定的,哪个字节代表什么含义,长度是多少, 先后顺序如何,全部都不允许改变。
每个Class文件的头4个字节被称为魔数。它的唯一作用就是确定这个Class文件是否为一个能被虚拟机接受的Class文件。不仅Class文件很过文件格式标准都有使用魔数来进行身份识的习惯。因为Class文件很难被修改。java中的魔数值为 0xCAFEBABE(咖啡宝贝)
紧接着魔数后面的4个字节是Class文件的版本号,第5和第6字节是次版本号,第7第8个字节是主版本号。java的版本号从45开始,jdk1.1后每个大版本发布后都向上加1。
次、主版本号之后就是常量池入口。常量池可以比喻为Class文件里的资源仓库,它是Class 文件结构中与其他项目关联最多的数据,通常也是占用Class文件空间最大的数据项目之一,另外,它 还是在Class文件中第一个出现的表类型数据项目。
常量池入口
因为常量池的容量不固定,所以在常量池入口需要放置一项u2类型的数据,代表常 量池容量计数值。这个容量计数是从1开始的而不是0。因为0代表特殊含义:“不引用任何一个常量池项目”
常量池中存放两大类常量:字面量和符号引用
在常量池结束之后,紧接着的2个字节代表访问标志(access_flags),这个标志用于识别一些类或 者接口层次的访问信息,包括:这个Class是类还是接口;是否定义为public类型;是否定义为abstract 类型;如果是类的话,是否被声明为final;等等。
类索引(this_class)和父类索引(super_class)都是一个u2类型的数据,而接口索引集合 (interfaces)是一组u2类型的数据的集合,Class文件中由这三项数据来确定该类型的继承关系。类索 引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。
Class文件格式除了上述之外还有 字段表集合、方法表集合、属性表集合。