呼唤远方
如果您使用以下的调试信息进行编译:javac -g),局部变量的名称保存在.class文件中。例如,以这个简单的类为例:class TestLocalVarNames {
public String aMethod(int arg) {
String local1 = "a string";
StringBuilder local2 = new StringBuilder();
return local2.append(local1).append(arg).toString();
}}编译后javac -g:vars TestLocalVarNames.java,局部变量的名称现在.class文件中。javap氏-l标志(“打印行号和局部变量表”)可以显示它们。javap -l -c TestLocalVarNames显示:class TestLocalVarNames extends java.lang.Object{TestLocalVarNames();
Code:
0: aload_0 1: invokespecial #1; //Method java/lang/Object."":()V
4: return
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LTestLocalVarNames;public java.lang.String aMethod(int);
Code:
0: ldc #2; //String a string
2: astore_2 3: new #3; //class java/lang/StringBuilder
6: dup 7: invokespecial #4; //Method java/lang/StringBuilder."":()V
10: astore_3 11: aload_3 12: aload_2 13: invokevirtual #5;
//Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: iload_1 17: invokevirtual #6; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
20: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
23: areturn LocalVariableTable:
Start Length Slot Name Signature
0 24 0 this LTestLocalVarNames;
0 24 1 arg I 3 21 2 local1 Ljava/lang/String;
11 13 3 local2 Ljava/lang/StringBuilder;}这个VM规范解释了我们在这里看到的:第4.7.9条LocalVariableTable属性:这个LocalVariableTable属性的可选变量长度属性。Code(第4.7.3节)属性。调试器可用于在方法执行期间确定给定局部变量的值。这个LocalVariableTable在每个插槽中存储变量的名称和类型,因此可以将它们与字节码匹配。调试器可以这样做“计算表达式”。然而,正如Erickson所说,没有办法通过正常反射访问这个表。如果你还决定这么做,我相信Java平台调试器体系结构(JPDA)会有帮助的(但我自己从来没用过)。