首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java & Javap:如何确定哪个对象接收Invokevirtual

Java & Javap:如何确定哪个对象接收Invokevirtual
EN

Stack Overflow用户
提问于 2014-10-21 23:47:52
回答 1查看 174关注 0票数 1

我正在查看Javap的输出。例如:

这段代码

代码语言:javascript
复制
    final Foo foo = new Foo(1,2);
    ... 
    new Callable<Integer>()
    {
        @Override
        public Integer call() throws Exception
        {
            return foo.doSomething();
        }

生成:

代码语言:javascript
复制
        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标识的。在类元数据中

代码语言:javascript
复制
    "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的信息。例如,我知道它在其一个字段中包含了这些数据:

代码语言:javascript
复制
        {
            "byteOffset": 37,
            "constantPoolIndex": null,
            "opCode": 18,
            "opCodeName": "ldc",
            "type": null,
            "tagName": "String",
            "tagValue": "NODE-1"
        }, 

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-22 00:11:00

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

假设foo是局部变量

  1. 调用new Foo(1,2);
  2. 结果,即对实例的引用的值,被复制并存储在局部变量foo中。
  3. ...stuff...
  4. 调用匿名类构造函数来创建新实例。
  5. 作为构造函数的一部分,局部变量foo的值的副本将被检索并推送到堆栈上。
  6. 该值将从堆栈中弹出,并分配给匿名类的val$foo字段(该变量即将关闭)
  7. ...stuff...
  8. 调用foo.something()时,JVM检索匿名类实例的字段val$foo的值。
  9. JVM取消该值以获取对象并调用该对象上的方法。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26498264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档