2013-02-13 4 views
6

私はjava.util.Collectionsからこの方法について質問があります:ジェネリックコレクションは、PECS

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<? super T>代わりのList<T>である理由<? super T>作品は、しかし、私は理解していないかを理解します。この状況では役に立たないと思います。
List<T>を使用するとうまくいくはずです。
可能であれば、理解するための例を教えてください。

ありがとうございました。

答えて

5

いいえ、意味があります。例えば、このような状況を考慮してください。

  • TInputStream
  • destList<Object>
  • srcは絶対にうまく動作しますList<FileInputStream>

であるです。もちろん、あなたこの状況でTObjectまたはFileInputStreamのいずれかを作ることができる - しかし、あなたはの署名で方法からこのを呼んでいた想像:あなたはそれはList<InputStream>だかわからない

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

- のみそれはList<? super InputStream>です。 copyのパラメータがの場合は、List<T>となり、詰まってしまいますが、と書いてあります。

宛先リストから必要なものについても意味があります。ちょうどに値Tを設定する必要があります。同様にソースリストに必要なのは、Tの値を取得できることです。 <? super T>および<? extends T>は、これらの要件をよく表しています。

+0

OK、すばらしい説明!どうもありがとう。 –

0

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

メソッドにリストを取り込もうとするときに、特定のタイプTを使用するように制限することができますが、制約が緩くなることがよくあります。例えば

、あなたが方法populateWithStudents(List<Student> list) があり、これは、あなたが学生が人を拡張していても、Studentオブジェクトでそれを埋めるためにList<Person>とそのメソッドを使用することができないことを意味Student extend Person

を持って言うことができます。

それどころか、populateWithStudents(List<? super Student> list)に変更することを許可したいと考えています。こうすることで、リストにStudentを入れることができれば、それがStudentオブジェクトのリストであっても、スーパークラスのリストであっても、それが許されます。

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

関連する問題