SomeAbstractClass
という名前の抽象クラスと、このスーパー クラスの少なくとも 10 個のサブクラスを持つ Java アプリケーションがあるとします。
Collection<? extends SomeAbstractClass>
単に使用する代わりに、ジェネリックでこの抽象スーパークラスを使用することの使用法は何ですかCollection<SomeAbstractClass>
たぶん、ジェネリック内の非常に基本的なものを見逃していたのでしょう。
これら 2 つの宣言の違い:
Collection<? extends A> c1;
Collection<A> c2;
c2 は A または任意のサブクラスのインスタンスを保持できますが、c1 は A (または A) の特定の未知のサブクラスまたは未知のクラスのサブクラスのいずれかのインスタンスを保持できます。
c2 に項目を追加することはできません。コンパイラはそれがどのような型であるかを認識していないためです。
さらに、c1 を c2 に代入 (キャスト) することはできません。c1 は c2 の型のサブクラスではありません。
ジェネリックのワイルドカードはコレクション タイプ用であり、通常は格納される要素用ではありません。
たとえば、引数を取るメソッドを想像してくださいList<Number>
。
public void calculateSum(List<Number> numbers) {
for (Number n: numbers) {
// calculate Sum
}
}
さて、次のように渡して整数の合計を計算したい場合List<Integer>
。Integer
(は のサブクラスであることに注意してくださいNumber
)
List<Integer> integers= new ArrayList<Integer>();
//Populate collection
calculateSum(integers); //Error
が のサブタイプであってもIntegers
、 のサブタイプでNumber
List<Integers>
はないため、これは機能しませんList<Number>
。、など をList<Number>
引き続き保存できることに注意してください。Integer
Float
Double
したがって、任意のタイプの合計を計算する一般的な方法を使用するには、次のNumber
ようにワイルドカードを使用します
public void calculateSum(List<? extends Number> numbers) {
for (Number n: numbers) {
// calculate Sum
}
}
これは、型が拡張されている場合、任意の型の数値の合計を計算しますNumber
あなたの場合、型は抽象的ですが、一般的にはすべてのサブクラスをCollection<SomeClass>
含むことができますが、含むことはできませんが、サブクラスのみであるため、違いはありません。SomeClass
Collection<? extends SomeClass>
SomeClass
自分で試すことができます。
List<Number> foo = new ArrayList<>();
foo.add(Integer.valueOf(0));
動作中
List<? extends Number> foo = new ArrayList<>();
foo.add(Integer.valueOf(0));
しません。エラーが表示されます"The method add(capture#1-of ? extends Number) in the type List<capture#1-of ? extends Number> is not applicable for the arguments (Integer)"