我已经读过很多关于此的内容了,我知道:
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)
我明白为什么你不能向wildcardList添加任何东西,因为它的类型可以是任何东西。但是,为什么可以添加到undefinedList? 他们似乎是一样的&amp;给出相同的行为,给出(1)和(2)。
答案 0 :(得分:2)
List undefinedList
和List<?> wildcardList
并不相同。第一个是原始类型,第二个是无界通配符。
如果要使用泛型类型但是您不知道或不关心实际类型参数是什么,请使用无界通配符。你不能把任何东西(除了null)放到这个列表中,你所了解的元素就是它们扩展了Object(实际上List<?>
与List<? extends Object>
相同)。无界通配符非常有用,因为如果您将天真地称为List<Object>
,则无法为其分配List<String>
,而您可以将List<String>
分配给List<?>
你应该(几乎)从不需要使用原始类型,它们只能与Java 5之前编写的代码兼容。
答案 1 :(得分:1)
List意味着这是一个未知类型的列表 - 因此你不会在创建时使用它(如在你的例子中),你通常将它用作方法参数。未绑定的通配符仅在用作方法中的参数时才非常有用,例如:
public void printList(List<?> items)
这可以迭代(任何)未知项目的列表。在这种情况下,列表项目将达到相同的目的,但客户端可能会收到警告。
如果您有以下内容:
public void printList(List<Object> items)
然后只能处理Object
列表 - 而不是列表字符串,整数等只有对象。
看看Unbounded Wildcards - 它很好地解释了
答案 2 :(得分:1)
List<?>
被读作某种未知类型的列表。作为一个程序员,你不能假设它是什么类型,你不能把任何东西放到除null之外的这样的集合中。但您可以放心,您的列表是类型安全的,因为编译器将保证您的类型安全。
List
基本上称为原始类型。也就是说它选择了编译器保证的类型安全性。因此,您可以将任何类型的元素放入该List中,从而破坏其不变量。不要再使用原始类型进行编码。它们基本上支持向后兼容性,因为java已经处于开发的第二个十年,当时Sun将泛型带到了表中,并且使用原始类型编写了大量代码,否则这些程序会破坏。
答案 3 :(得分:0)
“未定义”List
包含类型Object
的列表,它是所有类型的父类,因此List
不是类型安全的(可互换的)
这就是为什么:
List undefinedlist = new ArrayList<TYPE>(); //IS LIST OF OBJECTS
undefinedList.add(new Integer(1)); //WORKS
undefinedList.add(new String("string")); //WORKS
嗯..有效!
答案 4 :(得分:0)
List<?>
类型是通用的:您在代码中使用的任何类型都将在列表的方法中使用。因此,您可以执行list.add(item)
,只有在创建String
时才允许您加入List<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
,然后加Squid
。它并不关心,如果你只希望Giraffe
个对象在那里,它可能会成为编程错误的来源。
List list = new List();
list.add("A"); // <-- Allowed
list.add((Integer)10); // <-- Also allowed,
// but now the list contains not only strings
答案 5 :(得分:0)
基本上,?
位于以下
List<?> wildcardList = new ArrayList<TYPE>();
表示某种未知(特定)类型。因此,它不允许您将String
或Integer
之类的内容添加到某种未知类型的列表中,因为泛型是指类型安全的。
同时,在以下
中List<Object> listOfObject = new ArrayList<TYPE>();
你可以添加任何内容,因为Java中的所有内容都是Object
。所以这是类型安全的。
还有以下
List undefinedList = new ArrayList<TYPE>();
你告诉编译器你不想在那里使用泛型。这意味着您在undefinedList
上调用的每个方法都是非泛型的,因为您决定使用原始List
。集合框架中所有容器的非泛型版本都是为Object
(Java中的任何对象)而编写的。