注意区分class_index指向的是对应类的常量池,该CONSTANT_Class常量池指向一个全限定名的CONSTANT_Utf8字符串常量池
常量池部分的解析可以参考?id=3c1f3fac45837f95cc87fa6694a25b84&type=note
4.access_flags
该项2字节标志了所定义类或接口的类型信息
该文件中access_flags为0x0021 ,可见该类是public super类型。
5.this_class(当前类)
该项2字节标志了所定义类或接口的CONSTANT_Class常量池索引,最终指向全限定名”TestClass”
6.super_class(超类)
该项2字节标志了所定义类的超类的CONSTANT_Class常量池索引,最终指向全限定名”java/lang/Object”
7.interfaces_count/interfaces(接口数和接口)
首先2字节是在该类中直接实现或扩展的接口数,后面紧随若干个(接口数)2字节,代表所直接实现或扩展的接口的CONSTANT_Class常量池的索引
这里只实现了一个接口,就是5号常量池,即全限定名”TestInterface”所定义的接口
8.fields_count/fields(字段数和字段)
fields_count是类变量(静态变量)和实例变量(非静态变量)的字段数总和,与constant_pool组织形式类似,后面是fields_count个field_info,需要注意的是,当前类的字段不会包含其超类或父接口中继承的字段,也会包含在Java源文件中没有但是在编译时添加的一些字段。field_info结构如下:
field_info{ access_flags u2, name_index u2, descriptor_index u2, attributes_count u2, attributes attributes_info * attributes_cout }
(1).字段的accesss_flags与描述当前类的access_flags不同:
类中声明的字段,只能拥有ACC_PUBLIC、ACC_PRIVATE、ACC_PROTECTED三个标志中的一个。ACC_FINAL
和ACC_VOLATILE 不能同时设置。所有接口中声明的字段必须有ACC_PUBLIC、ACC_STATIC、ACC_FINAL 这三种标志。
(2).name_index为该字段的简单名称的CONSTANT_Utf8常量池索引
(3).descriptor_index为该字段的描述符的CONSTANT_Utf8常量池索引
(4).attributes_count和attributes是attributes_count个attribute_info结构所表述的属性集合。在字段域出现的属性有ConstantValue(final常量)、Deprecated(被禁用的指示符)、Synthetic(编译器产生的指示符)
属性出现在ClassFile、field_info、method_info、Code_attribute中。所有Java虚拟机必须能够识别Code、ConstantValue、Exception。对于能够正常实现Java/Java2平台类库的虚拟机必须能够识别InnerClass和Synthetic属性。
attribute_info的结构如下:
attribute_info{ attribute_name_index u2, attribute_length u4, info u1, }
attribute_name_index为描述属性的字符串名称(即上述列出属性名)的CONSTANT_Utf8常量池索引,
attribute_length为后面属性内容的长度
这里先介绍将字段可能用到的ConstantValue、Deprecated和Synthetic属性
(1).ConstantValue
u2 constantvalue_index 1
该属性用于描述值为常量的字段,并且在包含该属性的字段其access_flag必须为ACC_STATIC,以表明这是一个静态常量。
constantvalue_index指向提供常量值的常量池索引(此外,ConstantValue对应的属性的attribute_length始终为2)
(2).Deprecated
被@Deprecated所注释的字段、方法或类型,表示虽然该字段、方法或类型仍然存在,但是不建议使用,其在未来的版本中可能会被移除
Deprecated对应的属性的attribute_length值始终为0
(3).Synthetic
用来指明为编译器所产生的字段、方法或类型
同样,这是一个固定长度属性,其
对应的属性的attribute_length值始终为0