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