1

私はJavapの出力を見ています。例えば:

このコード

    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。たとえば、フィールドの 1 つに次のデータがあることがわかっています。

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

JVM はどのようにして何val$fooを指しているのかを知ることができますか?

4

1 に答える 1

2

JVM が保存する値を追跡するには、もう少しコンテキストが必要ですfoo

fooはローカル変数であると仮定します

  1. new Foo(1,2);呼び出される
  2. 結果 (インスタンスへの参照の値) がコピーされ、ローカル変数に格納されます。foo
  3. ...もの...
  4. 匿名クラス コンストラクターが呼び出され、新しいインスタンスが作成されます。
  5. コンストラクターの一部として、ローカル変数の値のコピーfooが取得され、スタックにプッシュされます。
  6. その値はスタックからポップされval$foo、匿名クラスのこのフィールドに割り当てられます (これはその変数を閉じています)
  7. ...もの...
  8. が呼び出されると、JVMは匿名クラス インスタンスfoo.something()のフィールドの値を取得します。val$foo
  9. JVM はその値を逆参照してオブジェクトを取得し、そのメソッドを呼び出します。
于 2014-10-22T00:11:00.640 に答える