5. 类索引
访问标志后面接下来的两个字节是类索引(this_class),它是一个对常量池的索引。在this_class位置的常量池入口必须为CONSTANT_Class_info表。该表由两个部分组成——tag和name_index。tag部分是代表其的标志位,name_index位置的常量池入口为一个包含了类或接口全限定名的CONSTANT_Utf8_info表。
6.父类索引
在class文件中,紧接在this_class之后是super_class项,它是一个两个字节的常量池索引。在super_class位置的常量池入口是一个指向该类超类全限定名的CONSTANT_Class_info入口。因为Java程序中所有对象的基类都是java.lang.Object类,除了Object类以外,常量池索引super_class对于所有的类均有效。对于Object类,super_class的值为0。对于接口,在常量池入口super_class位置的项为java.lang.Object
7.interfaces_count和interfaces
紧接着super_class的是interfaces_count,此项的含义为:在文件中出该类直接实现或者由接口所扩展的父接口的数量。在这个计数的后面,是名为interfaces的数组,它包含了对每个由该类或者接口直接实现的父接口的常量池索引。每个父接口都使用一个常量池中的CONSTANT_Class_info入口来描述,该CONSTANT_Class_info入口指向接口的全限定名。这个数组只容纳那些直接出现在类声明的implements子句或者接口声明的extends子句中的父接口。超类按照在implements子句和extends子句中出现的顺序在这个数组中显现。
8. fields_count和fields
在class文件中,紧接在interfaces后面的是对在该类或者接口中所声明的字段的描述。首先是名为fields_count的计数,它是类变量和实例变量的字段的数量总和。在这个计数后面的是不同长度的field_info表的序列(fields_count指出了序列中有多少个field_info表)。只有在文件中由类或者接口声明了的字段才能在fields列表中列出。在fields列表中,不列出从超类或者父接口继承而来的字段。另一方面,fields列表可能会包含在对应的Java源文件中没有叙述的字段,这是因为Java编译器可以会在编译时向类或者接口添加字段。
在Java中,描述字段的信息有:字段的作用域、是实例变量还是类变量(static)、可变性(final)、并发可见性(volatile)、可否序列化(trasient)、字段数据类型、字段名称。这些信息中,各个修饰符都是布尔值,要么有某个修饰符,要么没有,很适合使用标志位来表示。而字段叫什么名字、字段被定义为什么数据类型,这些都是无法固定的,只能引用常量池中的常量来描述。

字段修饰符放在access_flags项目中,它与类中的access_flags项目是非常相似的,都是一个u2的数据类型,其中可以设置 的标志位和含义如下表所示

跟随access_flags标志的是两项索引值:name_index和descriptor_index。它们都是对常量池的引用,分别代表着字段的简单名称及字段和方法的描述符。描述符的作用是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。根据描述符规则,基本数据类型(byte、char、double、float、int、long、short、boolean)及代表无返回值的void类型都用一个大写字符来表示,而对象类型则用字符L加对象的全限定名来表示。

对于数组类型,每一个维度将使用一个前置的"["字符来描述,如一个定义的"java.lang.String[][]"类型的二维数组,将被记录为:"[[Ljava/lang/String;",一个整型数组"int[]"将被记录为"[I"
用描述符来描述方法时,按照先参数列表,后返回值的顺序描述,参数列表按照参数的严格顺序放在一组小括号"()"之内。如方法void inc()的描述符为"()V",方法java.lang.String.toString()的描述符为"()Ljava/lang/String;"。
9.method_count和methods
紧接着field后面的是对在该类或者接口中所声明的方法的描述。其结构与fields一样,不一样的是访问标志。

10.attributes_count和attributes
class文件中最后的部分是属性,它给出了在该文件类或者接口所定义的属性的基本信息。属性部分由attributes_count开始,attributes_count是指出现在后续attributes列表的attribute_info表的数量总和。每个attribute_info的第一项是指向常量池中CONSTANT_Utf8_info表的引引,该表给出了属性的名称。
属性有许多种。Java虚拟机规范定义了几种属性,但任何人都可以创建他们自己的属性种类,并且把它们置于class文件中,Java虚拟机实现必须忽略任何不能识别的属性。
java虚拟机预设的9项虚拟机应当能识别的属性如下表所示。

作者 小诺N