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。这种情况用得很少)。