web-dev-qa-db-ja.com

型消去、オ​​ーバーライド、ジェネリック

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

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

オーバーライドしません

public void fooMethod(Class c)

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

 -名前の衝突:タイプSubClassのメソッドfooMethod(Class <?>)
は、
タイプSuperClassのfooMethod(Class)と同じ消去を持ちますが、それをオーバーライドしません
 
-タイプ
 SubClassのメソッドfooMethod(Class <?>)は、スーパークラスメソッド
をオーバーライドする必要があります。

編集: "Java -version "はJava(TM)2ランタイム環境、Standard Edition(ビルド1.5.0_16-b06-284)を言います。コードスニペットに関しては、それはすでにかなり上にあります;上記は以下のものを拡張します。

36
Henrik Paul

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

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

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

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

47
eljenso