做什么'开始'和'长度' LocalVariableTable中的属性是指

时间:2015-05-07 14:48:03

标签: java jvm bytecode java-bytecode-asm bytecode-manipulation

所以这是一个例子:

LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0     133     0  this   Lcom/my/class/Test;
               2     131     1     a   I
               4     129     2     b   I
               7     126     3     i   I
              10     123     4    i2   I
              16     117     5    o1   Ljava/lang/Integer;
              31     102     6    o2   Ljava/lang/Integer;

开始和长度是什么意思?为什么长度具有它的价值?为什么相同类型(整数)的长度不同?为什么长度可以更改,当我向类添加一些内容并重新编译它而不触及该特定的局部变量?

2 个答案:

答案 0 :(得分:9)

Start是此变量可见的起始字节码偏移量。长度是此变量可见的字节码字节数。通常从指向首先分配变量的字节码指令开始,或者指向方法参数和this的0。在你的情况下,似乎所有变量都在方法的末尾有效(每个变量都为start+length = 133),但是如果你在块中声明一些变量,它们的范围会更短。

请注意,局部变量表(LVT)是可选的调试信息。它不是程序执行所必需的,可以在编译期间使用-g:none关闭。此表的主要目的是使调试更方便:使用它可以确定每个字节码位置当前可见的变量,以便在变量窗格中显示它们,并在您退出变量范围后隐藏它们。此表也由java反编译器和代码分析器(如FindBugs)使用。

答案 1 :(得分:1)

根据jsl

内部局部变量表

u2 local_variable_table_length;
    {   u2 start_pc;
        u2 length;
        u2 name_index;
        u2 descriptor_index;
        u2 index;
    }

local_variable_table数组中的每个条目都表示一系列代码数组 局部变量具有值的偏移量。它还表明了指数 到当前帧的局部变量数组中,可以找到该局部变量。

现在你的start和length属性JSL说

start_pc,长度

The given local variable must have a value at indices into the code 

数组在区间[start_pc,start_pc + length],即之间 start_pc包含和start_pc +长度独占。

The value of start_pc must be a valid index into the code array of this 

Code属性,必须是指令操作码的索引。

The value of start_pc + length must either be a valid index into 

此Code属性的代码数组,并且是操作码的索引 一条指令,或者它必须是超出该代码数组末尾的第一个索引。

所以基本上开始对应于你的LineNumberTable