您的位置:首页 > 其它

实例分析Class字节码文件(二)

2017-10-10 00:17 183 查看
上篇必看:实例分析Class字节码文件(一)

四、字段表集合

字段表(field_info)集合用于描述接口或者类中声明的变量。

包括:类级变量 + 实例级变量(不包括局部变量)

注:

① 类级变量 = 类变量 = 静态变量 【
static int a;
】 存储在方法区;

②实例级变量 :没有
static
修饰符,只能通过实例对象访问;存储在对象中;

描述一个字段包含的方面有:

① 字段的作用域 :
public
private
protected


② 是实例级变量还是类级变量(是否被
static
修饰)

③ 可变性(是否被
final
修饰)

④ 并发可见性(是否被
volatile
修饰)

⑤ 是否可被序列化(
transient
修饰)

⑥ 字段数据类型(基本类型、对象、数组)

⑦ 字段名称

字段表结构如下:





access_flags结构如下:



所以
access_flags
应为 0x0002;查阅字节码文件,没问题



name_index : 字段的简单名称,值为对常量的引用



指向第5个常量 : ——> m

descriptor_index : 字段和方法的描述符,值为对常量的引用



指向第6个常量 : ——> I ,看到这个感觉有点问题,每个描述符都代表特殊的含义,如下:



descriptor_index一方面可以描述字段类型,如上表;另一方面还可以描述参数列表(包括数量、类型、顺序)和返回值。

注:

① 对于对象类型:用字符L和对象的全限定名来表示(
Ljava/lang/Object


② 对于数组:每一个维度用一个“[” 表示

java.lang.String[][]-->[[Ljava/lang/String


int[]-->[I


③ 用来描述方法时,按照参数列表,然后返回值的顺序描述,参数列表按照参数的严格顺序放在一组小括号“()”之内

void inc()--->()V


int indexOf(char[] source,


int sourceOff,


int sourceCount,


int targetOffset,


int targetCount,int fromIndex) -->([CII[CIII)I


attributes_count: 用于存放一些额外的信息,字段都可以在属性表中描述>=0个额外信息。如果属性表计数器为0,则attribute_info不占用空间。

本例子中:
attributes_count
为 0x0000.



注:

① 字段集合中不会列出从超类或者父类中继承(或接口继承)出来的字段,单有可能列出原本java中不存在的字段(内部类)

②字段无法重载,两个字段的数据类型、修饰符不管是否相同,都必须使用不一样的名称,但是对于字节码来说,如果两个字段的描述符不一样,那字段重名就是合法的。

五、方法表集合

同样先来看方法表结构:





这个结构和字段表相似,
access_flags
包括:



通过上表我们发现:并没有具体说明方法中的代码如何在字节码文件中存储的,其实是存放在方法属性表集合中一个名为“Code”的属性中。

注:在 方法表集合的前面,还有一个u2类型表示一共有几个方法;

在上一个的例子中值为:0x0002,代表有两个方法(inc()、)



然后才到方法表集合:

来看
access_flags
: 0x0001,很好理解
Acc_PUBLIC
为真

name_index
: 0x0007,指向第7个常量
<init>


descriptor_index
: 0x0008 ,指向第8个常量()V

attributes_count
: 0x0001,表示此方法的属性表集合有一项属性

attributes_info
: 0x0009,指向第9个常量Code,说明此属性是方法的字节码描述



注: 如果父类方法在子类中没有被重写(Override),方法表集合中就不会出现来自父类的方法信息。同样,有可能出现有编译器自动添加的方法,最经典的便是类构造器“”和实例构造器“”方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息