(編輯:前兩個答案刪除,一個爲回答這個問題,因爲它編輯之前站着一個爲是,如果不是完全錯誤的,至少接近)
如果使用(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."<init>":()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."<init>":()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 spec解釋了我們現在看到的:
§4.7.9 The LocalVariableTable
Attribute:
的LocalVariableTable
屬性是Code
的可選可變長度屬性( §4.7.3)屬性。調試器可能會使用它來確定在執行方法期間給定局部變量的值。
LocalVariableTable
在每個插槽中存儲變量的名稱和類型,因此可以將它們與字節碼進行匹配。調試器可以執行「評估表達式」。
正如erickson所說,雖然沒有辦法通過正常的反射來訪問這張表。如果你仍然決定這樣做,我相信Java Platform Debugger Architecture (JPDA)會有幫助(但我從來沒有用過它)。
所有好的答案!感謝大家的回覆和評論 - 這已經是一次有趣而深刻的討論。 – 2009-04-14 15:52:09
我發現[詳細反思教程](http://omtlab.com/java-reflection-tutorial/) – 2012-03-16 18:07:37
這是可能的。看我的[gist] [1]。適用於JDK 1.1到JDK 7. [1]:https://gist.github.com/2011728 – 2012-04-11 07:05:38