[英]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
是局部变量
new Foo(1,2);
is invoked foo
foo
foo
is retrieved and pushed on the stack foo
的值的副本并将其压入堆栈 val$foo
field of the anonymous class (this is closing over that variable) val$foo
字段(这是对该变量的关闭) foo.something()
is invoked, the JVM retrieves the value of the field val$foo
of the anonymous class instance foo.something()
,JVM检索匿名类实例的字段val$foo
的值
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.