简体   繁体   English

Java和Javap:如何确定哪个对象接收了调用虚拟

[英]Java & Javap: How to Determine Which Object Receives Invokevirtual

I am looking through the output of Javap. 我正在查看Javap的输出。 For example: 例如:

This code 这段代码

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

Generates: 产生:

        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
        }]

So I see that the object is identified in this case by val$foo . 因此,我看到在这种情况下该对象由val$foo标识。 And in the class metadata 在类元数据中

    "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
    }, 

But now I want to find out more about the original object foo . 但是现在我想了解更多有关原始对象foo For example, I know it has this data in one of its fields: 例如,我知道它在其字段之一中具有此数据:

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

How does the JVM know what val$foo points to? JVM如何知道val$foo指向什么?

You need a little more context to track the value the JVM stores for foo . 您需要更多上下文来跟踪JVM为foo存储的值。

Assuming foo is a local variable 假设foo是局部变量

  1. new Foo(1,2); is invoked 被调用
  2. The result, the value of the reference to the instance, is copied and stored in the local variable foo 结果(实例引用的值)被复制并存储在本地变量foo
  3. ...stuff... ...东西...
  4. The anonymous class constructor is invoked to create a new instance 匿名类构造函数被调用以创建新实例
  5. As part of its constructor, a copy of the value of the local variable foo is retrieved and pushed on the stack 作为其构造函数的一部分,将获取局部变量foo的值的副本并将其压入堆栈
  6. That value is popped from the stack and assigned to this val$foo field of the anonymous class (this is closing over that variable) 该值从堆栈中弹出,并分配给匿名类的val$foo字段(这是对该变量的关闭)
  7. ...stuff... ...东西...
  8. When foo.something() is invoked, the JVM retrieves the value of the field val$foo of the anonymous class instance 调用foo.something() ,JVM检索匿名类实例的字段val$foo的值
  9. The JVM dereferences that value to get the object and invokes the method on it JVM取消引用该值以获取对象并在其上调用方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM