我在 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.5m1
可以覆盖m2
即使m1
是私有的。如果.class
手动创建文件或组合.class
来自两个编译的文件,则可能会发生这种情况。
在我的示例中,我有课程A
并B
使用B extends A
. 我编译了这些类,使其A
包含一个public
名为的方法,f
并B
包含一个private
方法,也称为f
(首先声明两个方法public
,编译,复制A.class
到安全的地方,删除 in 的声明f
并A
更改为private
in B
,然后编译B
并使用保存的版本A.class
)。
现在运行它时,我当前的 Oracle JVM 输出A
(意味着调用了f
in方法)。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
}
谢谢,卡斯滕