jvm - Java 虚拟机规范 (JVMS) : Bug in "5.4.5 Method overriding"

标签 jvm bytecode

我在 2009 年 9 月 28 日提交了以下错误。遗憾的是,我仍然没有得到任何回应,规范的最终版本仍然不正确。这真的是一个错误吗?如果不是,为什么不呢?如果是,我该怎么办?

包含错误的部分是 5.4.5 (方法覆盖):http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4.5结合 INVOKEVIRTUAL 的描述操作码:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokevirtual

根据 5.4.5 m1可以覆盖 m2即使m1是私有(private)的。如果创建 .class,就会发生这种情况。手动文件或合并 .class从两个汇编。

在我的示例中,我有类(class) ABB extends A .我编译了这些类,以便 A包含 public名为 f 的方法和 B包含 private方法,也称为 f (首先声明两个方法 public ,编译,复制 A.class 到安全的地方,删除 f 中的 A 的声明并在 private 中更改为 B ,然后编译 B 并使用A.class 的保存版本)。

现在运行它时,我当前的 Oracle JVM 输出 A (意味着 f 中的方法 A 被调用)。根据规范,B应该是输出(意味着 f 中的方法 B 应该被调用)。

编辑:实际上,B.f应该解决。如果调用者不是 B,则调用可能会因为对已解析方法的访问权限检查而失败.但是,我认为方法解析部分是错误的。

我认为 5.4.5 中的定义应该检查 m1 的访问权限,不仅m2 .

public class A {
  public void f();
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String A
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

public class B extends A {
  private void f();
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String B
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

谢谢,
卡斯滕

最佳答案

你的问题终于解决了。 current version of the Java 8 JVM specification包含所需的说明:

5.4.5 Overriding

An instance method mC declared in class C overrides another instance method mA declared in class A iff either mC is the same as mA, or all of the following are true:

  • C is a subclass of A.
  • mC has the same name and descriptor as mA.
  • mC is not marked ACC_PRIVATE.
  • One of the following is true:
    • mA is marked ACC_PUBLIC; or is marked ACC_PROTECTED; or is marked neither ACC_PUBLIC nor ACC_PROTECTED nor ACC_PRIVATE and A belongs to the same run-time package as C.
    • mC overrides a method m' (m' distinct from mC and mA) such that m' overrides mA.


§4.10.1.5 “类型检查抽象和 native 方法”中还有另一个补充:

private methods and static methods are orthogonal to dynamic method dispatch, so they never override other methods (§5.4.5).



修复不到五年,与其他一些问题相比,这速度很快……

关于jvm - Java 虚拟机规范 (JVMS) : Bug in "5.4.5 Method overriding",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14753386/

相关文章:

java - 检测 Scala 程序中函数变化的最佳实践?

Java 8 lambda 表达式字节码一致性

java - ASM 在解释器上合并两个值对象

java - 卡尺错误 : CICompilerCount of 1 is invalid; must be at least 2

java - Swing 中的 JFrame 窗口是否运行在它们自己的独立线程上?

java - Resilience4j 断路器环位缓冲区大小配置

java - JVM实际上是如何读取并运行字节码的?一个巨大的 switch-case 语句?

java - JVM 的默认编码是什么?

java - 多线程中类加载器的行为

c++ - 如何将 ocaml 代码编译为 native 以供 C++ 使用