2012-02-28 14 views

答えて

11

はい。

List<Base>は、すべてがBaseに由来する異なるものの混合物を含むことができます。 List<? extend Base>には均質な項目が含まれています(つまり、すべてが特定の未知の型から派生しているという意味で、Baseから派生しています)。

List<? extends Base>List<T extends Base>の基本クラスです。したがって、List<T extends Base>List<? extends Base>とする任意のメソッドに渡すことができます。同じことは、List<Base>を取るメソッドには当てはまりません。

+6

特に、 'List <?'に 'Base'型のオブジェクトを追加することはできません。 Base> 'を拡張します。 –

+3

@LouisWasserman:それだけでなく、 'List <? 'に*任意の*オブジェクト(' null'を除く)を追加することはできません。 '? 'がどのような型を表しているのかわからないので、Base>を拡張します。 –

+0

@LouisWasserman:要するに、List <? extends Base>は、List <?を取り出すメソッドに渡すことができます。 Base>、List 、List 、またはリストを拡張しますか?では、リストを使用する理由は何ですか?私も困惑しているのは、List <? Base>とList を拡張しています。 '...'は、BaseまたはBaseから(直接的または間接的に)派生したものです。 – user113454

5

List<Base> listは、Baseまたはそのサブタイプのいずれかの要素を含むことができます。 JDKクラスといくつかの例:

List<Object> objects = new ArrayList<Object>(); 
objects.add(new Object()); // adding an Object instance 
objects.add("I am a String"); // a String instance is also an Object 
objects.add(Integer.valueOf(5)); // an Integer instance is also an Object 

しかし、あなたは要素を取得するときObjectが宣言リストのtypeパラメータであるので、あなたは、唯一のObjectクラスの変数に割り当てることができます。

Object first = objects.get(1); 
Object second = objects.get(2); 
Object third = objects.get(3); 

彼らの本当のランタイムクラスはまだObjectStringIntegerあるので、あなたはそれらのタイプにそれらをキャストし、そのように彼らと仕事が、正しく行われていない場合、このようなキャストがClassCastExceptionと、実行時に失敗する可能性がありますすることができ、それはですそのような方法でリストを扱うのは良い考えではありません。あなたがすることができないadd()任意のオブジェクトを、その中に、唯一null秒 -

List<? extends Base> listは、すでにダニエルPrydenさんのコメントで述べたので、実際に、変数の宣言のために指定されていない宣言です。

List<? extends String> list = new ArrayList<? extends String>(); 
list.add("a String")); // compile error! 

しかし、あなたはジェネリックメソッドのパラメータのために、このような有界ワイルドカード表現を使用することができます。追加することはできない<? extend E>ワイルドカードなしで

List<String> strings = Arrays.asList("a", "b"); 
List<Object> objects = new ArrayList<Object>(); 
objects.addAll(strings); 

boolean addAll(Collection<? extends E> c); 

これは、あなたがこのような何かを行うことができますList自体の例は、その署名これですaddAll()方法であり、ジェネリック型(配列とは異なる)が共変量ではないため、StringListObjectに変換します。つまり、List<String>であり、サブタイプはList<Object>ではありません。しかし、いずれもStringObjectです。そのため、限定されたワイルドカードを使用してメソッドパラメータを宣言する必要があります。List<String>サブタイプList<? extends Object>です。

また、境界のあるワイルドカードは、主に汎用メソッドパラメータで指定され、メソッドの戻り値の型や変数宣言では指定されません。

関連する問題