2017-05-16 1 views
0

リストにワイルドカードと下限ジェネリックを使用していますが、コンパイラはエラーをスローしています。Generics <? super A>は、リストのスーパータイプAを追加できません。

コード:

int intStart = 0;  
Number num = new Integer(2);     
List<? super Integer> listOfNumbers = new ArrayList<>(); 
listOfNumbers.add(intStart); 
listOfNumbers.add(num); //throws compiler error 

エラー:

方法が追加(キャプチャ#8のスーパー整数?)タイプのリストでは、引数には適用されません(番号)

List<? super Integer>では、タイプIntegerまたはそのスーパータイプのオブジェクトを追加する必要がありました。番号またはオブジェクト。 私はいくつかの議論を経てきましたが、なぜ上記のエラーになっているはずが見つかりませんでした。

+0

なしには、特定の質問に答えるん。再開。あなたの答えは – shmosel

答えて

3

List<? super Integer>で、Integer型またはそのスーパータイプのオブジェクトを追加する必要がありました。番号またはオブジェクト。

これは間違っています。 List<? super Integer>は、整数の任意のスーパータイプを保持できるリストであるを意味しません。それはの総称タイプが特定のスーパータイプの整数のリストであるリストを意味します。したがって、実際にはList<Object>List<Number>またはList<Integer>となる場合があります。これらのリストタイプにはいずれもIntegerが含まれていますが、Numberでは同じことが言えません。 NumberDoubleまたはLongである可能性がありますが、これはList<Integer>では許可されていません。

Long longValue = 2L; 
List<Integer> listOfIntegers = new ArrayList<>(); 
// listOfIntegers.add(longValue); 

コメント行は明らかにコンパイルされない、としませんする必要があります、それはもう少し具体的な作り、このスニペットを検討する

。しかし、これを追加した場合はどうなりますか:

Number longAsNumber = longValue; 
List<? super Integer> listOfSuper = listOfIntegers; 
listOfSuper.add(longAsNumber); 

これはあなたの質問のスニペットに相当します。最後の行をコンパイルすべきか?そうであれば、List<Integer>の汎用不変量に違反します。


あなたのご意見にお答えすると、List<? super Integer>はあなたの例では本当に不要です。より一般的な場合は、メソッドパラメータに柔軟性を追加することです。例えば、方法

void addInt(List<Integer> list) { 
    list.add(1); 
} 

は、不必要に制限的であろうList<Integer>を受け入れることができるであろう。パラメータタイプをList<? super Integer>に変更すると、メソッドはと同様にList<Number>を受け入れることができます。そのいずれかにIntegerの値を含めることができます。

これは、リストがで、対象となる汎用タイプがである場合にのみ有効です。メソッドがにリストから値を生成しようとすると、明確なスーパータイプがないので、タイプがObjectであると仮定することが強制されます。詳細については、What is PECS (Producer Extends Consumer Super)?

+0

thxです。コンパイラは、提供された汎用パラメータ型<?のリスト要素の型を把握できないと仮定します。スーパー整数>すなわち整数のリスト/数字のリストなど、もしそうであれば、そのような構成の実世界での使用は、私たちが整数をリストに追加できるようにすることなのでしょうか?リストでも同じことができます。varName = new ArrayList <>();宣言。だから、なぜ<?スーパー整数>?自分のコードで質問していることは分かっていますが、このような構造の背後にある設計の意思決定とその実際の使用を理解することが目的です。 – DevdattaK

+0

@DevdattaK更新情報をご覧ください。 – shmosel

+0

特にSOスレッドの更新をありがとう。それは私の質問を明確にします。 – DevdattaK

0

List<? super Integer>が少し奇妙です。 Integers(IntegerはIntegerに自動ボックス化されます)のみを追加できます。 List<Integer>で作業する可能性があるため、には許可されていないため、List<Number>List<? super Integer>の有効な割り当てですが、番号を追加することはできません。コンパイラは確実にわからないので、安全でない操作は許可されません。

つまり、List<? super Integer>を使用している場合、読み込みに安全な唯一のタイプはObjectであり、書き込みが安全な唯一のタイプはIntegerです。コンパイラは、安全でない操作であるため、許可しません。リンク重複の

(さらに読書のために、this answerはこれのジェネリック医薬品のかなり良い詳細な説明を与える)

関連する問題