Class文件分析(二)

    类索引和父类索引都是u2类型的数据,而接口索引集合是一组u2类型的数据集合,class文件中由这三项数据来确定这个类的继承关系。类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。因为多重继承的关系所以java的父类索引只有1个,除了java.lang.Object以外所有的java类都有父类,所以除了object所有的java类的父类索引都不为0。
    类索引和父类索引和接口索引按顺序在访问标志后面,类索引和父类索用u2类型的索引值表示,他们指向一个类型为CONSTANT_Class_info的类描述符常量(Class文件分析(一)有讲)通过该常量的索引值可以找到定义在CONSTANT_Utf8_info类型的常量中的全限定 名字符串。

    对于接口索引集合第一项为u2类型的数据为接口计数器表示索引表的容量如果没有实现接口则为0后面的接口索引表将不占用字节。


字段表用于描述接口或类中声明的变量。

跟随access_flags的是两项索引值:name_index和descriptor_index都是对常量池的引用。分别代表字段的简单名称以及字段和方法的描述符。

全限定名:“org/feixsoft/clazz”== org.feixsoft.class一般使用时会在最后加入一个‘;’标示全限定名结束。

简单名称:是指没有类型和参数修饰的方法或字段名称如inc()方法和m字段的简单名称就是'inc'和'm'。

方法和字段描述符:用来描述字段数据类型、方法参数列表(数量、类型、顺序)和返回值。根据描述规则基本数据类型和void都用一个大写字符表示,对象类型用L加对象全限定名表示。对于数组每一维度使用一个前置‘【’字符来描述如:java.lang.String[][]会被记录成'[[Ljava/lang/String';int[]被记录成‘I[’。

用描述符描述方法时先参数列表后返回值得顺序描述。如
void inc()->()V,
java.lang.String.toString()->()Ljava/lang/String,
int indexOf(char[]source,int sourceOffset,int sourceCount,char[]target,int targetOffset,int targetCount,int fromIndex)->([CII[CIII)I

对于TestClass.class来说字段表集合从0x000000f8开始,第一个u2类型的数据为容量计数器fields_count值为0x0001,说明这个类只有一个字段表数据,然后是access_flags标示值为0x0002标示private修饰的ACC_PRIVATE标示位为真其他为假。代表字段名称的name_index的值为0x0005,从前面的6-2代码清单中列出的常量表第五项为CONSTANT_Utf8_info类型的字符串值为“m",代表字段描述符的descriptor_index的值为0x0006指向常量池的字符串“I”根据这些信息我们可以推出源代码为private int m;



字段表集合不会列出从超类和弗雷接口中继承的字段,但有可能列出原本java中不存在的字段:内部类为了保持对外部类的访问性,会自动添加指向外部类实例的字段。在java中字段无法重载,但是对字节码来讲如果字段的描述符不一致那字段重名是合法的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值