4

私はこれについてたくさん読んだことがあり、次のことを知っています:

List<Object> listOfObject = new ArrayList<TYPE>();   // (0)
//can only work for TYPE == Object.
//if TYPE extends Object (and thus objects of type TYPE are Objects),
//this is not the same with Lists: List<Type> is not a List<Object>

今、私は次のことが大丈夫であることを読みました:

List undefinedList = new ArrayList<TYPE>();   // (1)
//works for ANY type (except for primitives)

List<?> wildcardList = new ArrayList<TYPE>();   // (2)  
//also works for ANY type (except for primitives)

それで:

List undefinedlist = new ArrayList(); //no TYPE specified
undefinedList.add(new Integer(1)); //WORKS
undefinedList.add(new String("string")); //WORKS

でも:

List<?> wildcardList = new ArrayList<TYPE>(); //TYPE specified
wildcardList.add(new TYPE(...)); //COMPILER ERROR

例:

List<?> wildcardList = new ArrayList<String>(); //TYPE specified
wildcardList.add(new String("string")); //COMPILER ERROR: The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (String)

そのタイプは何でもかまいませんので、ワイルドカードリストに何も追加できない理由を理解しています。しかし、なぜ undefinedList に追加できるのでしょうか?? (1) と (2) を考えると、それらは同じように見え、同じ動作を示します。

4

6 に答える 6

4

List undefinedListList<?> wildcardListあなたが自分自身を発見したように、同じではありません。1 つ目は raw タイプで、2 つ目は無制限のワイルドカードです。

ジェネリック型を使用したいが、実際の型パラメーターが何であるかがわからない、または気にしない場合は、無制限のワイルドカードを使用します。このリストには (null を除いて) 何も入れることができず、そこから得られる要素について知っていることは、それらが Object を拡張することだけです (実際にList<?>は と同じList<? extends Object>です)。無制限のワイルドカードは便利です。単純に何かを として宣言する場合List<Object>、たとえばそれに割り当てることはできませんが、aを a にList<String>割り当てることはできます。List<String>List<?>

生の型を使用する必要は (ほとんど) ないはずです。生の型は、Java 5 より前に記述されたコードとの互換性のためにのみ使用できます。

于 2013-02-20T15:34:04.780 に答える
2

List<?>不明なタイプのリストとして読み取られます。プログラマーとして、それがどのような型であるかを推測することはできず、そのようなコレクションに null 以外のものを入れることはできません。しかし、コンパイラがタイプ セーフを保証するので、リストがタイプ セーフであることに安心できます。

List基本的に raw 型と呼びます。つまり、コンパイラによって保証される型の安全性をオプトアウトしたということです。そのため、その invariants を破壊する List に任意のタイプの要素を入れることができます。生の型でコーディングしないでください。これらは基本的に下位互換性のためにサポートされています。なぜなら、Sun がジェネリックをテーブルに持ち込んだとき、Java はすでに 20 年間の開発段階にあり、生の型を使用して非常に多くのコードが記述されていたため、それらのプログラムは壊れていたからです。

于 2013-02-20T18:20:33.347 に答える
1

List は、これが不明なタイプのリストであることを意味します-そのため、作成時に(例のように)使用しないため、通常はメソッドパラメーターとして使用します。バインドされていないワイルドカードは、次のようなメソッドでパラメーターとして使用される場合にのみ本当に役立ちます。

public void printList(List<?> items)

これにより、(任意の)不明なアイテムのリストを反復できます。この場合、リスト項目は同じ目的を達成しますが、クライアントはおそらく警告を受け取ります。

次の場合:

public void printList(List<Object> items)

次に、Object文字列、整数などのリストではなく、オブジェクトのみのリストのみを処理できます。

Unbounded Wildcardsを見てください- それはかなりよく説明しています

于 2013-02-20T15:42:06.700 に答える
0

「未定義」には、すべてのタイプの父であるListタイプのリストが含まれているため、タイプセーフではありません(相互変換可能です)ObjectList

これが理由です:

List undefinedlist = new ArrayList<TYPE>(); //IS LIST OF OBJECTS
undefinedList.add(new Integer(1)); //WORKS
undefinedList.add(new String("string")); //WORKS

よく..動作します!

于 2013-02-20T15:25:28.643 に答える
-1

List<?>型はジェネリックです。クエスチョン マークの代わりに入力した型は、リストのメソッドで使用されます。だからあなたはすることができ、あなたが作成list.add(item)した場合にのみ入れることができます. 型安全第一。StringList<String>

List<String> list = new List<String>();
list.add("A");             // <-- Correct
list.add((Integer)10);     // <-- Error, it is a List of Strings

一方では、そこにList任意のObjectものを入れることができます。したがって、 を作成し、そこにListを入れてGiraffe、後で を作成できますSquidGiraffeオブジェクトだけがそこにあると予想される場合、それは気にせず、プログラミングエラーの原因になる可能性があります。

List list = new List();
list.add("A");             // <-- Allowed
list.add((Integer)10);     // <-- Also allowed,
                           // but now the list contains not only strings
于 2013-02-20T15:27:19.223 に答える