“Inside the Java Virtual Machine - Chapter 8 The Linking Model - Resolution of CONSTANT_Fieldref_info Entries”的一个错误

2020-09-10 09:36:31 +08:00
 JasonLaw

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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

962 次点击
所在节点    Java
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/705683

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX