注意,任何一个Class文件都对应着唯一一个类或接口的定义信息,但反过来说,类或接口并不一定都是定义在文件里(譬如类或接口也可以通过类加载器直接生成)。通俗的将任意一个有效的类或接口所应当满足的格式称为“Class文件格式”,实际上他并不一定以磁盘文件的形式存在。
Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部都是程序运行的必要数据,没有空隙存在。当遇到需要占用8字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。
根据Java虚拟机规范的规定,Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表。
无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。
表是由多个无符号数或者其他表作为数据项构成的符合数据类型,所有表都习惯性的以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表,他由下表所示的数据项构成。
类型 名称 数量 u4 magic 1 u2 minor_version 1 u2 major_version 1 u2 constant_pool_count 1 cp_info constant_pool constant_pool_count-1 u2 access_flags 1 u2 this_class 1 u2 super_class 1 u2 interfaces_count 1 u2 interfaces interfaces_count u2 fields_count 1 field_info fields fields_count u2 methods_count 1 method_info methods method_count u2 attributes_count 1 attribute_info attributes attributes_count
无论是无符号还是表,当需要描述同一类型但数量不定的多个数据时,经常会使用一个前置的容量计数器加若干个连续的数据项的形式,这时称这一系列连续的某一类型的数据为某一类型的集合。
Class的结构不像XML等描述语言,由于他没有任何分隔符号,所以在上表中的数据项,无论是顺序还是数量,甚至于数据存储的字节序(Byte Ordering,Class文件中字节序为Big-Endian)这样的细节,都是被严格限定的,哪个字节代表什么含义,长度是多少,先后顺序如何,都不允许改变。