36

誰かが私に理由を説明できますか

@Override
public void fooMethod(Class<?> c)

オーバーライドしません

public void fooMethod(Class c)

代わりに次のエラーが表示されます。

- 名前の衝突: メソッド fooMethod(Class<?>)
タイプ SubClass の fooMethod(Class) と同じ消去があります
SuperClass と入力しますが、オーバーライドしません

 - 型のメソッド fooMethod(Class<?>)
サブクラスはスーパークラス メソッドをオーバーライドする必要があります

?

編集: " java -version" は、Java(TM) 2 ランタイム環境、標準版 (ビルド 1.5.0_16-b06-284) を示します。コード スニペットに関しては、既にほぼ上にあります。上は下のものを拡張します。

4

2 に答える 2

47

の署名は、 の消去は単に( JLS 4.6fooMethod(Class<?>) ) であるため、消去後の署名と同じです。したがって、は のサブシグネチャですが、反対ではありません ( JLS 8.4.2 )。fooMethod(Class)Class<?>ClassfooMethod(Class)fooMethod(Class<?>)

インスタンス メソッドでオーバーライドするには、オーバーライドするメソッドがオーバーライドされたメソッドのサブシグネチャである必要があります ( JLS 8.4.8.1 )。ここでは明らかにそうではありません。

JLS に従って、サブクラス メソッドがスーパークラス メソッドをオーバーライドしないという事実を確立したので、型消去が発生した場合の実行時の影響を見てみましょう。これで、まったく「同じ」(同じ名前、同じパラメーター タイプ) に見える 2 つのメソッドができましたが、互いにオーバーライドしません。オーバーライドしない場合、サブタイプで別々のメソッドとして使用できる必要がありますが、実行時のシグネチャは同じです: 競合。したがって、Java はそれを禁止する必要があります。

生のパラメーター型を使用したジェネリック パラメーター型のオーバーライド許可されているのは、生の型が存在するのはこのためです。生の型は、レガシー コードとのやり取りに対応するための特定の不健全な型規則を備えた便利なメカニズムです。したがって、ここでの型システムは、サブクラスのメソッドスーパークラスのメソッドをオーバーライドすることを決定します。それら型の消去後に同一であり、競合が発生することはありません。この結果として、ライブラリは既存の非ジェネリック コードから独立して生成できます。

于 2009-02-02T10:23:23.067 に答える
-3

Class<?>より具体的だからですClass

たとえば、foo(Class<List>)オーバーライドできませんfoo(Class<Collection>)。この用語は忘れてしまいましたが、ジェネリクスを持つ型は、ジェネリックを持たない型とは常に異なります。

于 2009-02-02T09:04:10.950 に答える