質問:
サブクラスからアクセスされた場合、パラメータ化されたクラスのオブジェクトは非ジェネリックと見なされます。どうすればこれを克服できますか?
詳細:
基本クラスを考えてみましょう:
public class MyBaseClass {
protected List<Number> numbers = new ArrayList<Number>();
public MyBaseClass(){
//...
}
}
それでは、このクラスを拡張しましょう。
public class MyDerivedClass extends MyBaseClass {
public void addSomething() {
numbers.add(25.0f); //Warning about type-safety here
}
}
派生クラスでは、数値オブジェクトは生の型として表示されます。警告は次のとおりです。
型の安全性: メソッド add(Object) は生の型 List に属します。ジェネリック型 List への参照は、パラメーター化する必要があります。
型パラメーターを自分で追加しようとすると、コンパイル エラーが発生します。
numbers.<Number>add(25.0f); //Error here
私が見るエラーは次のとおりです。
List 型のメソッド add(Number) はジェネリックではありません。引数でパラメータ化することはできません
ただし、両方のクラスを同じ Java ソース ファイルに配置すると、この問題はなくなります。そもそも予告なし。これは、問題を説明するためのサンプルです。
List
私の実際のアプリケーションでは、取得したオブジェクトを適切な型に最初にキャストしなくても、派生クラスの から要素を取得し、それらに対してクラス固有の操作を実行できるようにしたいと考えています。
問題は型消去が原因であると思われますが、それを回避する方法がわかりません。
編集:
Fedora Core 16 で Eclipse 3.7.2 と Oracle JDK 1.6.0_30 を使用しています。コンパイラのコンプライアンスは、デフォルトのコンプライアンス設定で 1.6 に設定されています。前述したように、両方のクラスを同じ .java ファイルに配置すると、警告は表示されません。それらを別のファイルに配置した場合にのみ表示されます。
親クラスのリスト オブジェクトを直接操作するすべてのメソッドを定義することで、これを回避できます。派生クラスからこれを使用します。
しかし、なぜ警告が表示されるのかについてはまだ興味があります。回避策は次のとおりです。
MyBaseClass で:
protected void addNumberToList(Number num){
numbers.add(num);
}
そして派生クラスで:
public void addSomething() {
addNumberToList(25.0f);
}
List
同様に、オブジェクトを直接操作するすべての操作を基本クラスに含めることができます。