If resolution to the CONSTANT_Class_info completes successfully, the virtual machine performs the field lookup process using these steps:
- The virtual machine checks the referenced type for a field of the specified name and type. If the virtual machine discovers such a field, that field is the result of the successful field lookup.
- Otherwise, the virtual machine checks any interfaces directly implemented or extended by the type, and recursively, any superinterfaces of interfaces directly implemented or extended by the type, for a field of the specified name and type. If the virtual machine discovers such a field, that field is the result of the successful field lookup.
- Otherwise, if the type has a direct superclass, the virtual machine checks the type's direct superclass, and recursively all the superclasses of the type, for a field of the specified name and type. If the virtual machine discovers such a field, that field is the result of the successful field lookup.
- Otherwise, field lookup fails.
关于第 3 点,它说“if the type has a direct superclass, the virtual machine checks the type's direct superclass, and recursively all the superclasses of the type, for a field of the specified name and type”,这里遗漏了“对 superclass 的 superinterfaces 的检查”。
下面的例子可以证明,JVM 会检查 superclass 的 superinterfaces 。
import java.lang.Math;
public class Test {
public static void main(String[] args) {
System.out.println(A.i);
}
}
class A extends AParent {
}
class AParent implements B {
}
interface B {
int i = (int) (Math.random() * 100);
}
javac Test.java
之后,javap -c Test.class
的输出如下:
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: getstatic #3 // Field A.i:I
6: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
9: return
}
运行java Test
没有问题,可以看出 JVM 解析下标为 3 的 constant pool entry 时,最后会找到class A
,通过class A
会找到class AParent
,最后会找class AParent
的 superinterface interface B
。