Class 类文件学习(三)
访问标志和类接口
访问标志(access_flags):
(图0-1)
在常量池结束后,紧接的两个字节代码访问标志,这个标志用于识别一些类或者接口层次的访问信息,包括:这个Class 是类还是接口;是否定义为public 类型;是否定义为abstract;如果是类的话,是否被声明为final 等。具体的标志位以及标志的含义见如下表0-1:
(表0-1)
标志值的位值如下图0-2所示:
本例中 标志值是 0x0021 = 0x0020+0x0001 , 查表对应的 ACC_SUPER、ACC_PUBLIC 为1(真),也表明我们的例子是 public 类型。
类索引(this_class)、父类索引(super_class):
类索引和父类索引 都指向 CONSTANT_Class_info 的类描述符常量。
本例中 类索引 0x0003 指向 第3个常量,父类索引 0x0004 指向第4个常量,回顾第二篇内容,第3、4常量分别是 :
3、4常量也确实是 CONSTANT_Class_info 类型。
接口数量(interfaces_count):
本例中没有实现接口,所以接口数量为0。
字段表集合
接口之后跟着字段表集合:
字段表计数器(fields_count):
说明只有一个字段表
字段表(field_info):
field_info {
u2 access_flags;// 字段访问标志
u2 name_index;// 简单名称
u2 descriptor_index; // 描述符
u2 attributes_count; //
attribute_info attributes [attributes_count];
}
access_flags 标志值如下:
本例 attributes_count 为0 所有没有后面的attribute_info
方法表集合
接着是 方法表计数器
方法表计数器(methods_count)
本例有两个方法表。
方法表(method_info):
接下来是 方法表集合。
method_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes [attributes_count];
}
这里涉及到属性表,所有先插入属性表的简单介绍。
属性表相对于其他Class 文件中的其他数据项要求宽松了一些。
一个符合规则的属性表应该满足以下结构。
attribute_info {
u2 attribute_name_index;
u4 attribute_length;
u1 info [attribute_length];
}
大概了解了属性表的结构,继续上面的方法表查找。
得出第一个方法表如下:
继续找第二个方法表:
属性表集合
接下就是属性表了,首先是属性表计数器
属性表计数器(attributes_count):
本例有一个属性:
属性表(attribute_info):
刚才也说明了,属性表一般符合以下的结构:
attribute_info {
u2 attribute_name_index;
u4 attribute_length;
u1 info [attribute_length];
}
attribute_name_index 是一项指向 CONSTANT_Utf8_info 型常量的索引,常量池的名称代表了该属性的属性名称。
本例的 attribute_name_index 为0x000D 指向了第13个常量,一起回顾上一节看看第一13个常量是什么内容。
说明该属性是一个 SourceFile 属性。查表看其结构为:
SourceFile_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 sourcefile_index;
}
可以判断该 SourceFile 属性如下:
到此,本例, TestClass 文件的所有结构已经分析完了。
参考:
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4
《深入理解JAVA虚拟机.JVM高级特征与最佳实践》