( 편집 : 두 개의 이전 답변이 제거되었습니다. 하나는 편집 전에 서있는 질문에 대답하고 다른 하나는 절대적으로 잘못되지 않은 경우 적어도 그것에 가깝습니다. )
( 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 사양은 우리가 여기서보고있는 것을 설명합니다 :
4.7.9 LocalVariableTable
속성 :
이 LocalVariableTable
속성은 Code
(§4.7.3) 속성 의 선택적 가변 길이 속성입니다 . 메소드 실행 중에 지정된 로컬 변수의 값을 판별하기 위해 디버거에서 사용할 수 있습니다.
LocalVariableTable
상점 이름과 각 슬롯에서 변수의 타입이 있으므로은 바이트 코드들을 일치시킬 수있다. 디버거가 "표현식 평가"를 수행하는 방법입니다.
그러나 에릭슨이 말했듯이 정상적인 반사를 통해이 테이블에 액세스 할 수있는 방법이 없습니다. 그래도이 작업을 수행하기로 결정했다면 Java 플랫폼 디버거 아키텍처 (JPDA) 가 도움이 될 것이라고 생각합니다 (하지만 직접 사용하지는 않았습니다).