私は 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
オーバーライドできます。これは、ファイルを手動で作成したり、2 つのコンパイルを組み合わせたりした場合に発生する可能性があります。m2
m1
.class
.class
私の例では、クラスA
とB
with がありB extends A
ます。私はこれらのクラスをコンパイルして、名前付きのメソッドをA
含み、public
名前付きのメソッドも含むようにしました(最初に両方のメソッドを宣言し、コンパイルし、安全な場所にコピーし、 in の宣言を削除してinに変更し、コンパイルして保存されたバージョンの)。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
}
ありがとう、カルステン