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