15

これが私のプログラムです。コンパイル時エラーが発生する理由がわかりません。

import java.util.ArrayList;
import java.util.List;

public class Test {
public static void main(String[] args) {
    List< ? extends Number > list = new ArrayList<Integer>();

    list.add(6); // Compile Time Error

    System.out.println(list);

  }
}

しかし、次のプログラムは正常に動作します

import java.util.ArrayList;
import java.util.List;

public class Test {
public static void main(String[] args) {
    List< ? super Number > list = new ArrayList<Number>();

    list.add(6); 

    System.out.println(list);

    }
}

Eclipseからのエラー:

Eclipseからのエラーの説明は次のとおりです。

リスト型のメソッドadd(int、capture#1-of?extends Number)は、引数(int)には適用できません。

4

4 に答える 4

18

これは、最初のケースで行っていることがタイプセーフではないためです。あなたは「のサブクラス」listとして宣言し、それに挿入しようとしました。基になるリストの実際の実行時型と互換性があるという保証はまったくありません。あなたがしていることが意味をなさないので、コンパイラはここであなたを止めます。ListNumberIntegerInteger

極端な例として、次のことを考えてみましょう。

List< ? extends Object > list = new ArrayList<Integer>();
list.add("Hello, World!");

これが機能する場合は、が含まれているはずList<Integer>ですString

本当に機能させたい場合は、キャストして何をしているのかをコンパイラーに伝える必要があります。

((List<Integer>)list).add(6);

ただし、それでも型安全性に関する警告が表示されます。

2番目のケースは、リストが「Numberのスーパークラス」であることが保証されているために機能します。IntegerはのサブクラスでNumberあるため、任意のスーパークラス(それ自体を含む)に暗黙的に変換できるためNumber、値がリストの実際のタイプと互換性がないというリスクはありません。

詳細については、共変性と反変性の違いを確認することをお勧めします。

于 2012-09-24T14:36:30.290 に答える
4

ジェネリック型の一部としてListを持っているものに何かを追加することはできません。? extends ...

これを見てみましょう:

List< ? extends Number > list = new ArrayList<Integer>();

実際Listに使用しているのは。であることに注意してくださいArrayList<Integer>。このリストに、ではないものを追加することはできませんInteger。ただし、このタイプでList<? extends Number>は、たとえばaDoubleをリストに追加できます。これは、Doubleも拡張されるためNumberです。

詳細については、AngelikaLangerのJavaGenerics FAQの以下を参照してください。ワイルドカードパラメータ化型の参照変数を介してアクセス/アクセスできないメソッドとフィールドはどれですか?

于 2012-09-24T14:38:30.647 に答える
1

そのsuperとについてextendsこの質問を比較してください。

ワイルドカードで検索することもできます。

于 2012-09-24T14:36:46.217 に答える
0

これは機能しません:

List< ? extends Number > list = new ArrayList<Integer>();
list.add(6); // Compile Time Error

もしそうなら、あなたはこのような状況にたどり着くことができるからです。

class Apple extends Number  {}

List< ? extends Number > list = new ArrayList<Integer>();
list.add(new Apple()); //if it were to work, you'd have apples in what you'd think was a list of integers
于 2012-09-24T14:46:32.640 に答える