Я просматриваю результаты Javap. Например:Java & Javap: как определить, какой объект получает Invokevirtual
Этот код
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"
},
Как виртуальная машина знать, какие val$foo
очков?
Виртуальная машина Java знает, что VAL $ foo указывает на Foo объект (или некоторый подкласс Foo), потому что это так объявлено. И метод, вызываемый фактически, зависит от класса объекта, фактически используемого для invokevirtual. –