Java二进制Class文件格式解析
作者:网络转载 发布时间:[ 2013/10/21 10:01:59 ] 推荐标签:
(6) this_class
接下来的两个字节为this_class项,其值为一个对常量池表项的索引,即它指向一个常量池表项,而且该常量池表项必须为CONSTANT_Class_info表的结构。该表有一个name_index项,该项将指向另一个常量池表项,该表项包含了该类或者接口的完全限定名称。
(7) super_class
紧接着this_class之后的两个字节是super_class项,该项必须是对常量池表项的一个有效索引或者值为0。如果super_class项的值为0,则该Class文件必须表示java.lang.Object类。如果super_class项的值不为0,则又分为两种情况,若该Class文件表示一个类,则super_class项必须是对常量池中该类的超类的CONSTANT_Class_info表项的索引,这个超类和它的任何超类都不能是一个final类;若该Class文件表示一个接口,则super_class项必须是对常量池中表示java.lang.Object类的一个CONSTANT_Class_info表项的索引。
(8) interfaces_count和interfaces[ ]
紧接着super_class项后面的两个字节是interfaces_count项,此项表示由该类直接实现或者由该接口所扩展的超接口的数量。
紧接着interfaces_count项后面的是interfaces列表项,它包含了由该类直接实现或者由该接口所扩展的超接口的常量池索引,共计interfaces_count个索引。interfaces列表中的常量池索引按照该类型在源代码中给定的从左到右的顺序排列。
(9) fields_count和fields[ ]
接下来的是fields_count项,该项的值给出了fields列表项中的field_info表结构的数量,即表示了该Java类型声明的类变量和实例变量的个数总和。
fields列表项包含了在该Java类型中声明的所有字段的完整描述。fields列表中的每个field_info表项都完整地表示了一个字段的信息,包括该字段的名称、描述符和修饰符等。这些信息有的放在field_info表中,如修饰符;有的则放在field_info表所指向的常量池中,如名字和描述符。同前面的分析,fields列表项也是一个变长结构。
需要说明的是,只有在该Java类型中声明的字段才可能在fields列表中列出,fields列表中不包括从超类或者超接口中继承而来的字段信息。
(10) methods_count和methods[ ]
在Class文件中,紧接着fields后面的是对在该Java类型中所声明的方法的描述。首先是methods_count项,它占两个字节长度,它的值表示对该Java类型中声明的所有方法的总计数。methods_count项后面是methods列表项,它由methods_count个连续的method_info表构成。每个method_info表都包含了与一个方法相关的信息,如方法名、描述符(即方法的返回值及参数类型)以及一些其它信息。如果一个方法既非abstract也非native,那么该method_info表将包含该方法局部变量所需的栈空间长度、为方法所捕获的异常表、字节码序列以及可选的行号表和局部变量表等信息。
需要说明的是,只有在该Java类型中显式定义的方法才可能在fields列表中列出,fields列表中不包括从超类或者超接口中继承而来的方法信息。
(11) attributes_count和attributes[ ]
Class文件中后的部分是属性(attribute),它给出了在该Java类型中所定义的属性的基本信息。首先是attributes_count项,它占两个字节长度,它的值表示在后续的attributes列表中的attributes_info表的总个数。每个attributes_info表的第一项都是对常量池中CONSTANT_Utf8_info表项的一个索引,该表给出了此属性的名称。
需要说明的是,属性有很多种,在Class文件中的很多地方都出现了属性这一项,在顶层ClassFile表中有attributes属性项,在field_info表中也有attributes属性项,在method_info中也有attributes属性项,但是它们各有各的功能,详见上述分析。在《JVM Spec》(2nded)中,为ClassFile表结构的attributes列表项定义的属性是SourceFile属性,为field_info表结构的attributes列表项定义的属性是ConstantValue属性,为method_info表结构的attributes列表项定义的属性是Code属性和Exceptions属性。
总而言之,Class文件格式是一个规范性的格式。这个规范指的是,上面提到的这些表结构本身的规范性,以及这些表结构之间的包含关系的规范性。实际上,《JVM Spec》(2nded)中是通过表和项这两个概念来组织Class文件的格式的。首先,ClassFile表是Class文件外层的结构,换言之,这是Class文件的格式。其次,ClassFile表又是一些项组成的,这些项的内容都要符合《JVM Spec》(2nded)中定义的规范,具体来说,若这个项的类型是基本类型,该项的值要符合规范,例如magic项一定要是0xCAFEBABE,access_flags项的值一定要是有效的标志值等等;若这个项的类型是一个表名,即该项是一个数组项,那么该数组项列表中的每一个表项都要是一个合法的、规范的表,不能是一个规范中没有定义的新表,这是包含关系的规范性,同样,列表项中的每个表项本身也都要是符合其规范定义的表项,例如常量池列表中的某个CONSTANT_Class_info表的name_index项不是对一个CONSTANT_Utf8_info表结构的索引,那么这个常量池的表项不是一个合法的表项,因而这个常量池列表项是不符合规范的,因而整个文件是不符合规范的。

sales@spasvo.com