Class文件格式


Java 虚拟机规范

每个Class文件都是由8字节为单位的字节流组成,所有的16位、32位和64位长度的数据将被构造成 2个、4个和8个8字节单位来表示。多字节数据项总是按照Big-Endian①的顺序进行存储。在Java SDK中,访问这种格式的数据可以使用java.io.DataInput、java.io.DataOutput等接口和java.io.DataInputStream 和java.io.DataOutputStream等类来实现。
Class文件中定义了u1,u2和u4,分别代表了1、2和4个字节的无符号数
在Java SDK中这些类型的数据可以通过实现接口java.io.DataInput 中的readUnsignedByte、readUnsignedShort和readInt方法进行读取。


每一个Class文件对应于一个如下所示的ClassFile结构体。
ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; }


在Class文件中,各项按照严格顺序连续存放的,它们之间没有任何填充或对齐作为各项间的分隔符号。ClassFile结构体中,各项的含义描述如下

  • magic
    魔数,魔数的唯一作用是确定这个文件是否为一个能被虚拟机所接受的Class文件。魔数值固定为0xCAFEBABE,不会改变

  • minor_version、major_version
    副版本号和主版本号,minor_version和major_version的值分别表示Class文件的副、主版本。它们共同构成了Class文件的格式版本号。

  • constant_pool_count 常量池计数器
    constant_pool_count的值等于constant_pool表中的成员数加1。constant_pool表的索引值只有在大于0且小于constant_pool_count时才会被认为是有效的。

  • constant_pool[] 常量池
    constant_pool是一种表结构,它包含Class文件结构及其子结构中引用的所有字符串常量、类或接口名、字段名和其它常量。常量池中的每一项都具备相同的格式特征——第一个字节作为类型标记用于识别该项是哪种类型的常量,称为“tag byte”。常量池的索引范围是1至constant_pool_count−1。0是无效索引,表示不指向任何常量。CON-STANT_Long_info和CONSTANT_Double_info各占两个位置。比如下面的常量池:


    Class文件格式_第1张图片
    Paste_Image.png
  • access_flags
    访问标志access_flags是一种掩码标志,用于表示某个类或者接口的访问权限及基础属性。指出class文件定义的是类还是接口,访问级别是public还是private,等等。

  • this_class 和super_class
    类索引,this_class的值必须是对constant_pool表中项目的一个有效索引值。constant_pool表在这个索引处的项必须为CONSTANT_Class_info类型常量。u2类型的常量池索引,分别给出类名和超类名。class文件存储的类名类似完全限定名,但是把点换成了斜线,Java语言规范把这种名字叫作二进制名。除java.lang.Object之外,其他类都有超类,所以superClass只在Object.class中是0,在其他class文件中必须是有效的常量池索引。

  • interfaces_count
    接口计数器,interfaces_count的值表示当前类或接口的直接父接口数量。

  • interfaces[]
    接口表,interfaces[]数组中的每个成员的值必须是一个对constant_pool表中项目的一个有效索引值,它的长度为interfaces_count。给出该类实现的所有接口的名字。

+fields_count 和fields[]
字段计数器和字段表,fields_count的值表示当前Class文件fields[]数组的成员个数。fields[]数组中每一项都是一个field_info结构的数据项,它用于表示该类或接口声明的类字段或者实例字段。
field_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count]; }

  • methods_count 和methods[]
    方法计数器和方法表,methods_count的值表示当前Class文件methods[]数组的成员个数。Methods[]数组中每一项都是一个method_info结构的数据项。
    method_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count]; }

  • attributes_count和attributes[]
    属性计数器和属性表,attributes_count的值表示当前Class文件attributes表的成员个数。attributes表中每一项都是一个attribute_info结构的数据项。属性(Attributes)在Class文件格式中的ClassFile结构、field_info 结构,method_info结构和Code_attribute结构都有使用。
    所有属性的通用格式如下:
    attribute_info { u2 attribute_name_index; u4 attribute_length; u1 info[attribute_length]; }

你可能感兴趣的:(Class文件格式)