< 之间的区别?超级T>和 <?扩展 T>在 Java 中 [英] Difference between <? super T> and <? extends T> in Java
问题描述
List<有什么区别?super T>
和 List
?
我曾经使用 List
,但它不允许我向它添加元素 list.add(e)
,而 List
确实如此.
I used to use List<? extends T>
, but it does not allow me to add elements to it list.add(e)
, whereas the List<? super T>
does.
推荐答案
extends
Listfoo3
表示这些都是合法的赋值:
extends
The wildcard declaration of List<? extends Number> foo3
means that any of these are legal assignments:
List<? extends Number> foo3 = new ArrayList<Number>(); // Number "extends" Number (in this context)
List<? extends Number> foo3 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> foo3 = new ArrayList<Double>(); // Double extends Number
读取 - 鉴于上述可能的分配,您保证从
List foo3
读取什么类型的对象:
Reading - Given the above possible assignments, what type of object are you guaranteed to read from
List foo3
:
- 您可以读取
Number
因为任何可以分配给foo3
的列表都包含一个Number
或Number
的子类. - 您无法读取
Integer
,因为foo3
可能指向List
. - 您无法读取
Double
,因为foo3
可能指向List
.
- You can read a
Number
because any of the lists that could be assigned tofoo3
contain aNumber
or a subclass ofNumber
. - You can't read an
Integer
becausefoo3
could be pointing at aList<Double>
. - You can't read a
Double
becausefoo3
could be pointing at aList<Integer>
.
Writing - 鉴于上述可能的分配,您可以将什么类型的对象添加到 List foo3
对所有人> 以上可能的 ArrayList
赋值:
Writing - Given the above possible assignments, what type of object could you add to List foo3
that would be legal for all the above possible ArrayList
assignments:
- 您不能添加
Integer
,因为foo3
可能指向List
. - 您不能添加
Double
,因为foo3
可能指向List
. - 您不能添加
Number
,因为foo3
可能指向List
.
- You can't add an
Integer
becausefoo3
could be pointing at aList<Double>
. - You can't add a
Double
becausefoo3
could be pointing at aList<Integer>
. - You can't add a
Number
becausefoo3
could be pointing at aList<Integer>
.
您不能将任何对象添加到 List
因为你不能保证它真正指向的是什么类型的 List
,所以你不能保证该对象在那个 List
中是允许的>.唯一的保证"是您只能从中读取,并且您将获得 T
或 T
的子类.
You can't add any object to List<? extends T>
because you can't guarantee what kind of List
it is really pointing to, so you can't guarantee that the object is allowed in that List
. The only "guarantee" is that you can only read from it and you'll get a T
or subclass of T
.
现在考虑 List <?超级T>
.
Listfoo3
表示这些都是合法的赋值:
The wildcard declaration of List<? super Integer> foo3
means that any of these are legal assignments:
List<? super Integer> foo3 = new ArrayList<Integer>(); // Integer is a "superclass" of Integer (in this context)
List<? super Integer> foo3 = new ArrayList<Number>(); // Number is a superclass of Integer
List<? super Integer> foo3 = new ArrayList<Object>(); // Object is a superclass of Integer
阅读 - 鉴于上述可能的分配,当您从
List foo3
中读取时,您保证会收到什么类型的对象:
Reading - Given the above possible assignments, what type of object are you guaranteed to receive when you read from
List foo3
:
- 不能保证
Integer
因为foo3
可能指向List
或List
. - 不能保证
Number
,因为foo3
可能指向List
. - 唯一的保证是您将获得
Object
的实例或Object
的子类(但你不知道子类是什么).
- You aren't guaranteed an
Integer
becausefoo3
could be pointing at aList<Number>
orList<Object>
. - You aren't guaranteed a
Number
becausefoo3
could be pointing at aList<Object>
. - The only guarantee is that you will get an instance of an
Object
or subclass ofObject
(but you don't know what subclass).
Writing - 鉴于上述可能的分配,您可以将什么类型的对象添加到 List foo3
对所有人> 以上可能的 ArrayList
赋值:
Writing - Given the above possible assignments, what type of object could you add to List foo3
that would be legal for all the above possible ArrayList
assignments:
- 您可以添加
Integer
,因为在上述任何列表中都允许使用Integer
. - 您可以添加
Integer
子类的实例,因为上述任何列表中都允许Integer
子类的实例. - 您不能添加
Double
,因为foo3
可能指向ArrayList
. - 您不能添加
Number
,因为foo3
可能指向ArrayList
. - 您不能添加
Object
,因为foo3
可能指向ArrayList
.
- You can add an
Integer
because anInteger
is allowed in any of above lists. - You can add an instance of a subclass of
Integer
because an instance of a subclass ofInteger
is allowed in any of the above lists. - You can't add a
Double
becausefoo3
could be pointing at anArrayList<Integer>
. - You can't add a
Number
becausefoo3
could be pointing at anArrayList<Integer>
. - You can't add an
Object
becausefoo3
could be pointing at anArrayList<Integer>
.
PECS
记住PECS:生产者扩展,消费者超级".
Producer Extends" - 如果您需要一个
List
来生成T
值(您想阅读T
s 从列表中),你需要用声明它?扩展 T
,例如<代码>列表.但是您不能添加到此列表中.
"Producer Extends" - If you need a
List
to produceT
values (you want to readT
s from the list), you need to declare it with? extends T
, e.g.List<? extends Integer>
. But you cannot add to this list.
Consumer Super" - 如果您需要一个 List
来使用 T
值(您想编写 T
s 到列表中),你需要用 声明它吗?super T
,例如<代码>列表.但是不能保证您可以从此列表中读取什么类型的对象.
"Consumer Super" - If you need a List
to consume T
values (you want to write T
s into the list), you need to declare it with ? super T
, e.g. List<? super Integer>
. But there are no guarantees what type of object you may read from this list.
如果您需要读取和写入列表,则需要完全声明它,不要使用通配符,例如List
.
If you need to both read from and write to a list, you need to declare it exactly with no wildcards, e.g. List<Integer>
.
注意 Java 泛型常见问题解答中的这个示例.注意源列表src
(生产列表)如何使用extends
,目标列表dest
(消费列表)如何使用super代码>:
Note this example from the Java Generics FAQ. Note how the source list src
(the producing list) uses extends
, and the destination list dest
(the consuming list) uses super
:
public class Collections {
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
for (int i = 0; i < src.size(); i++)
dest.set(i, src.get(i));
}
}
这篇关于< 之间的区别?超级T>和 <?扩展 T>在 Java 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!