2014-10-21 7 views
1

Javap의 출력을 살펴보고 있습니다. 예를 들어 :Java 및 Javap : Invokevirtual을 수신하는 개체를 확인하는 방법

이 코드

final Foo foo = new Foo(1,2); 
    ... 
    new Callable<Integer>() 
    { 
     @Override 
     public Integer call() throws Exception 
     { 
      return foo.doSomething(); 
     } 

는 생성 :

 jvmOperations": [{ 
      "byteOffset": 0, 
      "constantPoolIndex": null, 
      "opCode": 42, 
      "opCodeName": "aload_0", 
      "type": null, 
      "tagName": null, 
      "tagValue": null 
     }, { 
      "byteOffset": 1, 
      "constantPoolIndex": null, 
      "opCode": 180, 
      "opCodeName": "getfield", 
      "type": null, 
      "tagName": "Field", 
      "tagValue": "val$foo:Lcom/example/graph/demo/Foo;" 
     }, { 
      "byteOffset": 4, 
      "constantPoolIndex": null, 
      "opCode": 182, 
      "opCodeName": "invokevirtual", 
      "type": null, 
      "tagName": "Method", 
      "tagValue": "com/example/graph/demo/Foo.doSomething:()Ljava/lang/Integer;" 
     }, { 
      "byteOffset": 7, 
      "constantPoolIndex": null, 
      "opCode": 176, 
      "opCodeName": "areturn", 
      "type": null, 
      "tagName": null, 
      "tagValue": null 
     }] 

그래서 나는 객체가 val$foo에 의해이 경우 식별되는 것을 알 수있다. 그리고 클래스의 메타 데이터에

"classMetaData": { 
     "classId": "com/example/Main$1.class", 
     "sourceName": "Main.java", 
     "isInterface": false, 
     "isClass": true, 
     "accessModifiers": ["final"], 
     "superClassName": "java/lang/Object", 
     "implementedInterfaces": ["java/util/concurrent/Callable"], 
     "jreTargetVersion": "51.0", 
     "fields": ["val$foo"], 
     "fieldModifiers": { 
      "val$foo": ["final"] 
     }, 
     "methodInformationMap": {}, 
     "interface": false, 
     "class": true 
    }, 

는하지만 지금은 원래 개체 foo에 대한 자세한 내용을 찾고 싶어요. 어떻게 JVM이 무슨 val$foo 점을 알 수 있습니까

 { 
      "byteOffset": 37, 
      "constantPoolIndex": null, 
      "opCode": 18, 
      "opCodeName": "ldc", 
      "type": null, 
      "tagName": "String", 
      "tagValue": "NODE-1" 
     }, 

예를 들어, 나는 그것의 필드 중 하나에서이 데이터가 알아?

+0

JVM은 그 발을 $으로 알고 foo는 Foo를 가리 킵니다. 객체 (또는 Foo의 일부 하위 클래스)가 선언 된 방식이기 때문입니다. 그리고 실제로 호출 된 메소드는 invokevirtual에 실제로 사용 된 객체의 클래스에 따라 다릅니다. –

답변

2

foo에 대한 JVM 저장 값을 추적하려면 좀 더 많은 컨텍스트가 필요합니다. foo 가정

  1. new Foo(1,2);
  2. 결과를 호출 된 로컬 변수의 인스턴스에 대한 참조 값이 복사 및 로컬 변수 foo
  3. ... 물건에 저장된 ...
  4. 익명 클래스 생성자가 호출되어 새 인스턴스를 만듭니다.
  5. 생성자의 일부로 th 즉 로컬 변수 foo 검색하고
  6. 그 값이 스택으로부터 팝 (이 그 위에 가변 닫는)
  7. 물건 ... ...
  8. 익명 클래스 val$foo이 필드에 할당 된 스택에 푸시 foo.something()를 호출하면
  9. 는, JVM이
  10. JVM이 객체를 얻기 위해 그 값을 역 참조 익명의 클래스 인스턴스의 필드 val$foo의 값을 검색하고 그 위에 메소드를 호출
+0

감사합니다 Sotirios, 내가 필요로하는 데이터의 일부가 정수 풀에도있을 수 있습니다. –