Java和Javap:如何确定哪个对象接收invokevirtual。



我正在查看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的信息。例如,我知道它的一个字段中有这样的数据:

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

JVM如何知道val$foo指向什么?

您需要更多的上下文来跟踪JVM为foo存储的值。

假设foo是局部变量

  1. 调用new Foo(1,2);
  2. 结果,即实例引用的值,被复制并存储在本地变量foo
  3. 。。。东西
  4. 调用匿名类构造函数以创建新实例
  5. 作为其构造函数的一部分,检索局部变量foo的值的副本并将其推送到堆栈上
  6. 该值从堆栈中弹出,并分配给匿名类的val$foo字段(这是对该变量的关闭)
  7. 。。。东西
  8. 当调用foo.something()时,JVM检索匿名类实例的字段val$foo的值
  9. JVM取消引用该值以获取对象,并调用对象上的方法

相关内容

  • 没有找到相关文章

最新更新