“Inside the Java Virtual Machine – Chapter 8 The Linking Model – Resolution of CONSTANT_Fieldref_info Entries”的一个错误
資深大佬 : JasonLaw 2
在Inside the Java Virtual Machine – Chapter 8 The Linking Model – Resolution of CONSTANT_Fieldref_info Entries中,它说:
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。
大佬有話說 (0)