class字节码文件组成(2)

55 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情

class字节码文件组成(1)中介绍了(魔数、版本号、常量池计数器、常量池数据区、访问标志)。这里了解剩余的class文件结构信息。 类索引、父类索引、接口计数器、接口信息数据、字段计数器、字段信息数据、方法计数器、方法信息数据、属性计数器、属性信息数据

了解class文件其他的结构信息

类索引(this_class)

类索引的值必须是constant_pool表中的一个有效索引值。constant_pool表在这个索引处的项必须是CONSTANT_CLASS_INFO类型的常量,表示这个Class文件所定义的类或接口。

父类索引(super_class)

父类索引

对于类来说,super_class的值必须为0或者是constant_pool表中的一个有效索引值。如果super_class的值不为0,那么constant_pool表在这个索引处的项必须是CONSTANT_CLASS_INFO类型的常量,表示这个Class文件所定义的直接父类。当前类的直接父类以及他的所有间接父类的access_flag都不可以带有ACC_FINAL标识

对于接口来说也是一样super_class必须为constant_pool表中的一个有效索引。且constant_pool在此索引处的项必须为代表java.lang.Object的CONSTANT_CLASS_INFO类型的常量。

如果class文件的Super_class的值为0,那么它只能定义为java.lang.objec类,只有它没有父类。

接口计数器(interfaces_count)

标识当前类直接接口的数量

接口信息数据区

Interfaces[interface_coount]。接口信息表Interfaces[]中的每一个成员的值都必须为constant_info表中的一个有效的索引值。constant_pool在对应索引处的项必须是CONSTANT_CLASS_INFO类型的常量。

且接口信息表中的索引值是有序的,即编译器生成的class文件实现接口的顺序。

字段计数器(fields_count)

字段计数器,表示当前类声明的类字段和实例字段(成员变量)的个数。

字段信息数据区(fields[])

字段表,长度为fields_count。字段表fields[]中的每一个成员都是fields_info结构的数据项,用于描述该字段的完整信息。

字段表fields[]用于记录当前接口或类声明的所有字段信息,但不包括从父类或父接口中继承过来的部分。

方法计数器(method_count)

方法计数器,表示当前类定义的方法个数。

方法数据区(methods[])

方法表,长度为method_count。方法表methods[]中的每一个成员都是method_info结构的数据项,用于描述该方法的完整信息。

如果一个method_info结构中的access_flags既不包含ACC_NATIVE也不包含ACC_ABSTRACT标识。那么标识当前方法可以被jvm直接加载,而不需要依赖其他类。

方法表methods[]记录着当前接口或接口中定义的所有方法,包括静态方法、实例方法、初始化方法(init 、cinit)。不包括从父类或父接口中继承过来的方法。

属性计数器

属性个数

属性数据区

attributes[]。属性表中的每一项都是一个Attribute_info结构

小结

根据以上总结,一个class文件可以表示为

classFile{
  u4          			magic;//魔数
  u2         			minor_version;//服版本号(一般不用管)
  u2         			major_version;//主版本号  jdk1.0为45,高本版递增
  u2				constant_pool_count;//常量池计数器
  cp_info			constant_pool[constant_pool_count-1];//常量池数据区
  u2				access_flags;//访问标志
  u2				this_class;//类索引。是constant_pool中的一个有效索引
  u2				super_class;//父类索引。只有object此项为0
  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]//属性数据区
}