java List<Object> 和 List<?> 有什么区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12340808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the difference between List<Object> and List<?>
提问by Aldsjers Dostrnik
Before are all you burn me alive, I must say that I have googling this question many times and I still can't understand the difference between List<Object> and List<?>
在你把我活活烧死之前,我必须说我已经谷歌搜索了很多次这个问题,但我仍然无法理解 List<Object> 和 List<?> 之间的区别。
All books I've read say that in Java every class is implicitly a subclass of Object.
我读过的所有书籍都说,在 Java 中,每个类都隐含地是 Object 的子类。
However I saw herethe follwing code:
但是我在这里看到了以下代码:
public static void printList(List<Object> list) {
for (Object elem : list)
System.out.println(elem + " ");
System.out.println();
}
This code is wrong (intentionally for educational purposes) and according to the author the reason is:
这段代码是错误的(故意用于教育目的),据作者说原因是:
[...] prints only a list of Object instances; it cannot print List<Integer>, List<String>, List<Double>, and so on, because they are not subtypes of List<Object>
[...] 只打印一个 Object 实例列表;它不能打印List<Integer>、List<String>、List<Double>等,因为它们不是 List<Object> 的子类型
The solution is:
解决办法是:
public static void printList(List<?> list) {
for (Object elem: list)
System.out.print(elem + " ");
System.out.println();
}
As you can see, the only difference is the first line:
如您所见,唯一的区别是第一行:
public static void printList(List<Object> list) {
public static void printList(List<?> list) {
This is the reason of my question: What's the difference between List<Object> and List<?> ?
这就是我的问题的原因: List<Object> 和 List<?> 之间有什么区别?
After all is Objectsuperclass of everything or not?
毕竟Object是不是所有东西的超类?
If someone can help me with a simple explanation (I'm new with Java) I'll appreciate.
如果有人能帮我做一个简单的解释(我是 Java 新手),我将不胜感激。
Thank you in advance.
先感谢您。
采纳答案by Roberto Mereghetti
Explanation:
解释:
? is a "wildcard". You can use it in different ways:
? 是一个“通配符”。您可以通过不同方式使用它:
unbounded wildcard:
无界通配符:
?
wildcard with upper bound:
带上限的通配符:
? extends Object (or another class)
wildcard with lower bound
带下限的通配符
? super Object (or another class)
Examples:
例子:
List <?> list;
you can assign to list
any List with any type parameter.
您可以list
使用任何类型参数分配给任何列表。
List<? extends Number> list;
you can assign to list any List with a type parameter Number (or Integer, Float, ecc)
您可以分配列出任何带有类型参数 Number(或 Integer、Float、ecc)的 List
List<? super Integer> list;
you can assign to list any List with a type parameter Integer, or a type in the type gerarchy of Integer(Number,Comparable, Serializable, Object ...)
您可以分配列出任何带有类型参数 Integer 的 List,或 Integer(Number,Comparable, Serializable, Object ...)
Summary:
概括:
So the declaration
所以声明
List<Object> list;
is similar to
类似于
List<? super Object> list;
because you can assign to "list" only a List of Objects; then you can use the list in this way:
因为您只能分配给“列表”一个对象列表;那么你可以这样使用列表:
list = new ArrayList<Object>();
list.add(new String(""));
list.add(new Integer(3));
回答by meriton
That String
is a subtype of Object
does not mean that List<String>
is a subtype of List<Object>
. If it were, the following code would compile:
那String
是 的子类型Object
并不意味着List<String>
是 的子类型List<Object>
。如果是,下面的代码将编译:
List<String> strings = new ArrayList<String>();
List<Object> objects = strings;
objects.add((Integer) 1);
strings.get(0).charAt(0); // but the Integer 1 does not have a charAt method ...
Therefore, List<String>
is not a subtype of List<Object>
.
因此,List<String>
不是 的子类型List<Object>
。
Both List<String>
and List<Object>
are subtypes of List<?>
. But because List<?>
is the more general type, you can't know what type the add method takes:
这两个List<String>
和List<Object>
的亚型List<?>
。但是因为List<?>
是更通用的类型,你无法知道 add 方法采用的是什么类型:
List<String> strings = new ArrayList<String>();
List<?> objects = strings;
objects.add((Integer) 1); // does not compile
回答by Johan Sj?berg
One of the major differences is how you can modify the lists. The following works well
主要区别之一是如何修改列表。以下效果很好
List<Object> l1;
l1.add(new Object()); // OK
while the second case produces a compilation error.
而第二种情况会产生编译错误。
List<?> l2;
l2.add(new Object()); // Compile error
The reasons for that I think has been debated a few times on the site already. In short,<?>
means a(as in one) specificyet unknowntype. Since that type is not known compile-time, you're not allowed to modify the list.
我认为其原因已经在该网站上进行了几次辩论。总之,<?>
意味着一个(如在一个)特定还未知类型。由于该类型在编译时未知,因此您不能修改列表。
回答by Dan D.
You can basically use both version in similar ways. However, there is one big difference. Let's declare the following:
您基本上可以以类似的方式使用这两个版本。但是,有一个很大的不同。让我们声明以下内容:
List<Object> list1 = new ArrayList<Object>();
List<?> list2 = new ArrayList<String>();
Now, let's try the code below:
现在,让我们试试下面的代码:
list1.add("");// this works fine
list2.add("");// this one issues a compile error
Someone could ask why this. This is because in List<Object>
, the code tells you that you have Object
or subtypes there, but in List<?>
you could have the same thing but you don't know exactly what. Someone could add String
or Double
and then try to read and cast to Integer
. But again, it is not possible.
有人可能会问为什么会这样。这是因为在 中List<Object>
,代码告诉您那里有Object
或子类型,但在 中List<?>
您可以拥有相同的东西,但您不知道究竟是什么。有人可以添加String
或Double
,然后尝试读取并投射到Integer
. 但同样,这是不可能的。
There may be other differences that I don't remember about now.
可能还有其他差异,我现在不记得了。
回答by TimK
Object is the superclass of String but List<Object> is not the superclass of List<String>. If it were, this would be a problem:
Object 是 String 的超类,但 List<Object> 不是 List<String> 的超类。如果是这样,这将是一个问题:
List<String> strings = ...
addObject(strings);
...
void addObjects(List<Object> objects) {
objects.add(new Object());
}
Now strings contains an element that isn't a String.
现在字符串包含一个不是字符串的元素。
回答by davidmontoyago
This code is wrong (intentionally for educational purposes) and according to the author the reason is:
[...] prints only a list of Object instances; it cannot print List, List, List, and so on, because they are not subtypes of List
这段代码是错误的(故意用于教育目的),据作者说原因是:
[...] 只打印一个 Object 实例列表;它不能打印 List、List、List 等,因为它们不是 List 的子类型
This is because parameterized types are invariant, for instance for the classes X and Y, List<X>
is neither a subtype nor a supertype of List<Y>
.
这是因为参数化类型是不变的,例如对于类 X 和 Y,List<X>
既不是 的子类型也不是超类型List<Y>
。
The difference resides in that the unbounded wildcard type?
means that the type is unknown and you can′t assume anything about it. A List<?>
is type safe, you can′t put any element other than null
in it and you can′t assume anything about the type of the object it contains.
不同之处在于无界通配符类型?
意味着该类型是未知的,您无法对此进行任何假设。AList<?>
是类型安全的,你不能在其中放置任何元素null
,也不能假设它包含的对象的类型。
List<Object>
obviously means that the List can contain objects of any type.
List<Object>
显然意味着 List 可以包含任何类型的对象。
回答by viswarajramji
public static void main(String args[]){
List<? super Object> list=new ArrayList<>();
list.add("A");//works
List<Object> list1=new ArrayList<>();
list1.add("B");//works
List<?> list2=new ArrayList<>();
list2.add("11");//compile time error;
List<? extends Object> list4=new ArrayList<>();
list4.add("123");//compile Time error
}
List< ? extend Object> & List< ? > doesn't allow to add anything follow this to know the reason :enter link description hereBut on the other hand List< ? super Object> allows to add values to List because the problem in the link provided doesn't exists .
列表< ? 扩展对象> & 列表< ? > 不允许在此之后添加任何内容以了解原因:在此处输入链接描述但另一方面 List< ? super Object> 允许向 List 添加值,因为提供的链接中的问题不存在。