Java におけるとの違い [重複] 質問する

Java におけるとの違い [重複] 質問する

List<? super T>との違いは何ですかList<? extends T>?

以前は を使用していましたList<? extends T>が、 では要素を追加できませんlist.add(e)が、 ではList<? super T>追加できます。

ベストアンサー1

extends

のワイルドカード宣言は、List<? extends Number> foo3次のいずれかが有効な割り当てであることを意味します。

List<? extends Number> foo3 = new ArrayList<Number>();  // Number "extends" Number (in this context)
List<? extends Number> foo3 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> foo3 = new ArrayList<Double>();  // Double extends Number
  1. 読み取り- 上記の可能な割り当てを考慮すると、どのタイプのオブジェクトから読み取ることができることが保証されますかList foo3?

    • Numberのいずれかのリストにまたは のサブクラスがfoo3含まれるように割り当てることができるため、を読み取ることができます。NumberNumber
    • は を指している可能性があるIntegerため、を読み取ることはできません。foo3List<Double>
    • は を指している可能性があるDoubleため、を読み取ることはできません。foo3List<Integer>
  2. ライティング- 上記の可能な割り当てを前提として、上記の可能な割り当てすべてList foo3に対して合法となるオブジェクトの種類はどれですか。ArrayList

    • は を指している可能性があるIntegerため、を追加することはできません。foo3List<Double>
    • は を指している可能性があるDoubleため、を追加することはできません。foo3List<Integer>
    • は を指している可能性があるNumberため、を追加することはできません。foo3List<Integer>

実際に が指しているList<? extends T>種類を保証できないため、にオブジェクトを追加することはできません。したがって、その オブジェクトがその で許可されることは保証できません。唯一の「保証」は、 からのみ読み取りが可能で、または のサブクラスが取得されることです。ListListTT

super

ここで考えてみましょうList <? super T>

のワイルドカード宣言は、List<? super Integer> foo3次のいずれかが有効な割り当てであることを意味します。

List<? super Integer> foo3 = new ArrayList<Integer>();  // Integer is a "superclass" of Integer (in this context)
List<? super Integer> foo3 = new ArrayList<Number>();   // Number is a superclass of Integer
List<? super Integer> foo3 = new ArrayList<Object>();   // Object is a superclass of Integer
  1. 読み取り- 上記の可能な割り当てを考慮すると、次から読み取るときに受け取ることが保証されるオブジェクトの種類は次のとおりですList foo3

    • は またはを指している可能性があるIntegerため、が保証されるわけではありません。foo3List<Number>List<Object>
    • は を指している可能性があるNumberため、が保証されるわけではありません。foo3List<Object>
    • 唯一保証は、 のインスタンスObjectまたはそのサブクラスObject(ただし、どのサブクラスかはわかりません) が取得されることです。
  2. ライティング- 上記の可能な割り当てを前提として、上記の可能な割り当てすべてList foo3に対して合法となるオブジェクトの種類はどれですか。ArrayList

    • 上記のリストではIntegerが許可されているため、を追加できます。Integer
    • 上記のリストのいずれでも のIntegerサブクラスのインスタンスが許可されているため、のサブクラスのインスタンスを追加できます。Integer
    • は を指している可能性があるDoubleため、を追加することはできません。foo3ArrayList<Integer>
    • は を指している可能性があるNumberため、を追加することはできません。foo3ArrayList<Integer>
    • は を指している可能性があるObjectため、を追加することはできません。foo3ArrayList<Integer>

ペック

PECS を思い出してください: 「生産者が拡張し、消費者がスーパー」

  • 「プロデューサー拡張」List - 値を生成するためにが必要な場合(リストから をT読み取りたい場合)、 で宣言する必要があります(例: ) 。ただし、このリストに追加することはできません。T? extends TList<? extends Integer>

  • 「コンシューマー スーパー」List - 値を消費するためにが必要な場合T(Tリストに を書き込む場合)、 を使用して宣言する必要があります? super T(例: ) List<? super Integer>。ただし、このリストから読み取るオブジェクトのタイプについては保証されません。

  • リストの読み取りと書き込みの両方を実行する必要がある場合は、ワイルドカードを使用せずにリストを正確に宣言する必要があります (例: ) List<Integer>

注記Java Generics FAQからのこの例ソース リストsrc(生成リスト) が を使用しextends、宛先リストdest(消費リスト) が を使用する方法に注意してくださいsuper

public class Collections { 
  public static <T> void copy(List<? super T> dest, List<? extends T> src) {
      for (int i = 0; i < src.size(); i++) 
        dest.set(i, src.get(i)); 
  } 
}

こちらもご覧くださいList<? extends Number> データ構造に追加するにはどうすればよいですか?

おすすめ記事