は、次のコードを考えてみましょキャストなぜスーパークラスジェネリック型が消去されていない/
ジェネリックのすべてのタイプを宣言しなければなりませんか? (クラスAのジェネリック型はクラスBで宣言されたにもかかわらず)
それとも、私は基本的には何かが足りないのですか?
は、次のコードを考えてみましょキャストなぜスーパークラスジェネリック型が消去されていない/
ジェネリックのすべてのタイプを宣言しなければなりませんか? (クラスAのジェネリック型はクラスBで宣言されたにもかかわらず)
それとも、私は基本的には何かが足りないのですか?
はJLS 4.8 Raw Typesを参照してください:
生タイプが添付型引数リストなしでジェネリック型宣言の名前を取ることによって形成された参照型は、[...]になるように定義されます。
スーパークラス(それぞれ、スーパー)生タイプのは、パラメータ化された呼び出しの任意のスーパークラス(スーパー)の消失です。言い換えれば
あなたは<>
なしB
を使用する場合、それは基本的にすべてジェネリック、すべての方法まで、すべての基底クラスとインタフェースを消去、生タイプとなり、すなわちあるA
とB
「はwerenかのようになり、ジェネリックT:
String name = b.getValue()
が失敗した理由
getValue()
は今
Object
を返しているので、ある
class A {
Object t;
public Object getValue() {
return t;
}
}
class B extends A {
//some code here..
}
。JLSで
注次のコメント:
生タイプの使用が唯一のレガシーコードの互換性への譲歩として許可されています。 Javaプログラミング言語にジェネリックスが導入された後に生のコードをコード内で使用することは、絶対に避けてください。 Javaプログラミング言語の将来のバージョンでは、生の型の使用を禁止する可能性があります。
要約すると、は、ではありません。生の型を使用しないようにコードを修正してください。
次のようにして、しかし、右辺を短縮することができます。
B<Integer> b = new B<>();
クラスBの一般的な値は、単に任意の汎用性を無視A(ロング)のクラスA
方法TのgetValue()からの1つとはリンク長のgetValue(であろう)を有していませんラッピングクラスで。
あなたが整数のgetValueを(必要な場合)、単に
class B extends A<Integer> {}
EDITのために行く:あなたは、応答を変更することができます、あなたの質問を変更:)
Bは、Sは数を拡張(Bと考えられていますT)(Aを拡張しているため)。 変数を生の型Bとして保存すると、適切に宣言されていても、その変数は暗黙的にB(Object、Object)になります。
はあなたが同じ問題で終わる一覧
List l = new ArrayList<String>();
String s = l.get(0);
でテストを行います。
私は以前のものがNumberとLongの間の混乱を引き起こすので、質問を編集しました。 –
OPはむしろ、一般的な 'S'がクラス' A'とは無関係で、 'getValue'はクラス' B'の格闘のために 'Long'を返すはずですが、 'A' getValue'の' Long'を返すために 'B'が変数を定義している間に一般的な' S'を提供しなければなりませんが、 'Object'を返します。 – SomeJavaGuy
あなたは 'B.getValue()'の宣言で重要な部分を省略しました。 –
の間に、getValue()の動作を変更したくないときに、Bのメソッドをオーバーライドする必要がありますか?また、Aの型は、消去するためにBのLong型として宣言されています。 –
@JimGarrisonしかし、 'getValue'の格闘は' A'クラスにあります。 – SomeJavaGuy