深入理解Android:Java虚拟机ART
上QQ阅读APP看书,第一时间看更新

2.5.4 LocalVariableTable属性

LocalVariableTable属性用于描述一个函数具备变量相关的信息。图2-10和图2-11分别展示了该属性对应的数据结构和一个示例。

图2-10 LocalVariableTable数据结构

图2-11为LocalVariableTable的示例。

图2-11 LocalVariableTable示例

由图2-10可知,LocalVariableTable_attribute里最重要的元素其实是local_variable_table数组,其元素的成员变量含义如下。

·start_pc和length这两个参数决定了一个局部变量在code数组中的有效范围。

·name_index:此局部变量的名字,指向Utf8_info常量项。

·descriptor_index:此局部变量的类型,也指向Utf8_info常量项,其内容是Field Descriptor字符串描述。

接着来看图2-11中的示例。首先是源码,其中包含x、exception和y三个局部变量(隐含还包含了一个this变量)。源码下面是用javap反解析class文件得到的结果,解释如下。

·每个非static函数都会自动创建一个叫作this的本地变量,代表当前是在哪个对象上调用此函数。注意,this对象位于局部变量数组第1个位置(Slot=0)。this作用范围贯穿整个函数,所以从Start=0开始,作用范围为Length=20。

·x变量的Signature=I,表明其为int型变量,作用范围为code[2,2+3)。

·exception变量为java.lang.IllegalAccessError类型,作用范围为code[9,9+7)。

·y变量类型为整型,作用范围为code[19,19+1)。

关于LocalVariableTable属性,笔者还需要再强调几点:

·LocalVariableTable属性只能附属于某个Code_attribute。

·LocalVariableTable属性描述了一个函数中所有的局部变量的信息,这个信息由LocalVariableTable_attribute里的local_variable_table项表示。注意,对于非静态函数,每一个函数的第一个局部变量都会设置成代表调用对象的this变量。

·local_variable_table可描述一个局部变量在一个函数中的作用域。作用域的概念映射到Code_attribute的code数组上就是该变量从code数组哪个位置开始,到哪个位置结束。

·local_variable_table数据结构中有一个slot变量。根据规范,JVM在调用一个函数的时候,会创建一个局部变量数组,slot表示这个变量在该数组中的位置。注意,JVM虽然对函数调用的规则有要求,但是具体实现却并不强制。所以,各位读者只需了解有这么一回事就行了。

作用域的表示

作用域的表示有全包和半包两种:

全包的格式是[begin,end],即作用范围从begin开始,到end结束,并且包括end。

半包的格式是[begin,end)(从begin开始,到end结束,但不包括end)或者(begin,end](从begin开始,不包括begin,到end结束,并且包括end。这种情况用得很少)。