Class文件结构全面解析(下)

书接上一回,分享了Class文件的主要构成,同时也详细分析了魔数、次版本号、主版本号、常量池集合、访问标志的构造,接下来我们就继续学习。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

类索引和父类索引

类索引(this_class)和父类索引(super_class)都是一个u2类型的数据,类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类全限定名。由于java语言不允许多重继承,所以父类索引只有一个。

类索引和父类索引各自指向常量池中类型为CONSTANT_Class_info的类描述符,再通过类描述符中的索引值找到常量池中类型为CONSTANT_Utf8_info的字符串。再来看一下之前的Class文件例子:

Class文件结构全面解析(下)

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

结合之前javap分析出来的常量池内容:

#3 = Class #17 // OneMoreStudy #4 = Class #18 // java/lang/Object #17 = Utf8 OneMoreStudy #18 = Utf8 java/lang/Object

类索引为0x0003,去常量池里找索引为3的类描述符,类描述符中的索引为17,再去找索引为17的字符串,就是“OneMoreStudy”。

父类索引为0x0004,去常量池里找索引为4的类描述符,类描述符中的索引为18,再去常量池里找索引为18的字符串,就是“java/lang/Object”。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

接口索引集合

接口索引集合(interface)是一组u2类型的数据的集合,由于java语言允许实现多个接口,所以接口索引也有多个,它们按照implements语句后的接口顺序从左到右依次排列在接口索引集合中。接口索引集合的第一项数据是接口集合计数值(interfaces_count),表示有多少接口索引。如果该类没有实现任何接口,那么该计数值为0,后面的接口索引表不占任何字节。之前的例子OneMoreStudy类没有实现任何接口,所以接口集合计数值就是0,如下图:

Class文件结构全面解析(下)

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

字段表集合

字段表(field_info)是用来描述接口或类中声明的变量。包括类级变量(静态变量)和实例级变量(成员变量),但是不包括在方法内部声明的局部变量。具体结构如下表:

类型 名称 数量 描述
u2   access_flags   1   字段的访问标志  
u2   name_index   1   字段的简单名称索引  
u2   descriptor_index   1   字段的描述符索引  
u2   attributes_count   1   字段的属性计数值  
attribute_info   attributes   attributes_count   字段的属性  

字段表中的access_flags,和类的access_flags是非常类似的,但是标识和含义是不一样的。具体如下表:

标志名称 标志值 含义
ACC_PUBLIC   0x0001   字段是否public  
ACC_PRIVATE   0x0002   字段是否private  
ACC_PROTECTED   0x0004   字段是否protected  
ACC_STATIC   0x0008   字段是否static  
ACC_FINAL   0x0010   字段是否为final  
ACC_VOLATILE   0x0040   字段是否volatile  
ACC_TRANSIENT   0x0080   字段是否transient  
ACC_SYNTHETIC   0x1000   字段是否由编译器自动产生的  
ACC_ENUM   0x4000   字段是否enum  

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

这里提到了简单名称、描述符,和全限定名有什么区别呢?稍微说一下。

简单名称是没有类型和参数修饰的方法或字段名称,比如OneMoreStudy类中的number字段和plusOne()方法的简单名称分别是“number”和“plusOne”。

全限定名是把类全名中的“.”替换成“/”就可以了,比如java.lang.Object类的全限定名就是“java/lang/Object”。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgwwp.html