Java虚拟机规范(JVMS):“5.4.5方法覆盖”中的错误

时间:2013-02-07 14:24:43

标签: jvm bytecode

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

包含错误的部分是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。如果手动创建.class文件或合并两个编辑中的.class,则会发生这种情况。

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

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

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

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

m2

谢谢, 卡斯滕

1 个答案:

答案 0 :(得分:1)

最后,您的问题已得到解决。 current version of the Java 8 JVM specification包含所需的说明:

  

5.4.5覆盖

     

在C类中声明的实例方法m C 会覆盖另一个实例方法m A   在A类中声明如果m C 与m A 相同,或者所有以下都是真的:

     
      
  • C是A的子类。
  •   
  • m C 与m A 具有相同的名称和描述符。
  •   
  • m C 未标记为ACC_PRIVATE。
  •   
  • 以下之一是真的:   
        
    • m A 标记为ACC_PUBLIC;或标记为ACC_PROTECTED;或者没有标记   ACC_PUBLIC或ACC_PROTECTED也不是ACC_PRIVATE和A属于同一个   运行时包为C。
    •   
    • m C 覆盖方法m'(m'与m C 和m A 不同),使m'覆盖m A
    •   
  •   

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

  

私有方法和静态方法与动态方法调度正交,   所以他们永远不会覆盖其他方法(§5.4.5)。

修复不到五年,与其他一些问题相比,这个问题很快......