6

からこの方法について質問がありますjava.util.Collections

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));   
  }   
}

仕組みは理解していますが、最初のパラメーターがではなく である<? super T>理由がわかりません。この状況では駄目だと思います。 を使用しても同様に機能するはずですよね? 可能であれば、それを理解するためにいくつかの例を教えてください。 List<? super T>List<T>
List<T>

ありがとう。

4

2 に答える 2

5

いいえ、それは理にかなっています。たとえば、次の状況を考えてみましょう。

  • TInputStream
  • destですList<Object>
  • srcですList<FileInputStream>

それは絶対にうまくいきます。もちろん、この状況ではまたはのいずれかを作成できますが、次のシグネチャを持つメソッドからこれを呼び出すと想像してください。TObjectFileInputStream

public void doSomething(List<? super InputStream> streams) {
    // I want to use copy in here for some reason
}

List<InputStream>あなたはそれが- であることだけを知りませんList<? super InputStream>。のdestパラメータcopyだけだっ List<T>たら行き詰まります... しかし、このように書かれているので問題ありません。

また、宛先リストに必要なものに関しても意味があります。その中で値を設定できる必要があるだけTです。同様に、ソース リストに必要なのは、Tそこから値を取得できることだけです。<? super T>そして、<? extends T>それらの要件をうまく表現します。

于 2013-02-13T14:51:46.363 に答える
0

リストが使用されている理由を詳しく説明すると、もう少し明確になります。

メソッドがリストにデータを入力する場合、特定の型 T を使用するように制限できますが、制限を緩和したい場合がよくあります。

たとえば、あなたがメソッドを持っていて、あなたが持っているとしpopulateWithStudents(List<Student> list) ましょうStudent extend Person

List<Person>これは、 Student が Person を拡張していても、そのメソッドを a で使用して Student オブジェクトで満たすことはできないことを意味します。

一方、それを許可したい場合は、 に変更しpopulateWithStudents(List<? super Student> list)ます。このように、リストに Student を収めることができれば、それが Student オブジェクトのリストであろうと、そのスーパークラスのリストであろうと、許可されます。

これは明らかに入力するときだけではありませんが、この例は概念を理解するのに役立ちます。

于 2013-02-13T14:53:21.750 に答える