<? 之间的区别 超级 T> 和 <? 在 Java 中扩展 T>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4343202/
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
Difference between <? super T> and <? extends T> in Java
提问by Anand
What is the difference between List<? super T>
and List<? extends T>
?
List<? super T>
和 和有List<? extends T>
什么区别?
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.
我曾经使用List<? extends T>
,但它不允许我向它添加元素list.add(e)
,而允许List<? super T>
。
采纳答案by Bert F
extends
extends
The wildcard declaration of List<? extends Number> foo3
means that any of these are legal assignments:
的通配符声明List<? extends Number> foo3
意味着这些都是合法的赋值:
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
Reading- Given the above possible assignments, what type of object are you guaranteed to read from
List foo3
:- 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>
.
- You can read a
Writing- Given the above possible assignments, what type of object could you add to
List foo3
that would be legal for allthe above possibleArrayList
assignments:- 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>
.
- You can't add an
阅读- 鉴于上述可能的分配,你保证从什么类型的对象读取
List foo3
:- 您可以读取 a ,
Number
因为任何可以分配为foo3
包含 aNumber
或 的子类的列表Number
。 - 您无法读取 an
Integer
因为foo3
可能指向 aList<Double>
。 - 您无法读取 a
Double
因为foo3
可能指向 aList<Integer>
。
- 您可以读取 a ,
写作- 鉴于上述可能的分配,您可以添加什么类型的对象
List foo3
对于上述所有可能的ArrayList
分配都是合法的:- 您不能添加 an
Integer
因为foo3
可能指向 aList<Double>
。 - 您不能添加 a
Double
因为foo3
可能指向 aList<Integer>
。 - 您不能添加 a
Number
因为foo3
可能指向 aList<Integer>
。
- 您不能添加 an
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<? extends T>
因为你不能保证List
它真正指向的是什么类型,所以你不能保证该对象被允许在那个List
. 唯一的“保证”是,你只能从它读,你会得到一个T
或子类 T
。
super
super
Now consider List <? super T>
.
现在考虑List <? super T>
。
The wildcard declaration of List<? super Integer> foo3
means that any of these are legal assignments:
的通配符声明List<? super Integer> foo3
意味着这些都是合法的赋值:
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
Reading- Given the above possible assignments, what type of object are you guaranteed to receive when you read from
List foo3
:- 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 onlyguarantee is that you will get an instance of an
Object
or subclass ofObject
(but you don't know what subclass).
- You aren't guaranteed an
Writing- Given the above possible assignments, what type of object could you add to
List foo3
that would be legal for allthe above possibleArrayList
assignments:- 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>
.
- You can add an
阅读- 鉴于上述可能的分配,您在阅读时保证收到什么类型的对象
List foo3
:- 你不能保证 an
Integer
因为foo3
可能指向 aList<Number>
或List<Object>
。 - 你不能保证 a
Number
因为foo3
可能指向 aList<Object>
。 - 该唯一的保证是,你会得到一个实例
Object
或子类的Object
(但你不知道什么是子类)。
- 你不能保证 an
写作- 鉴于上述可能的分配,您可以添加什么类型的对象
List foo3
对于上述所有可能的ArrayList
分配都是合法的:- 您可以添加 ,
Integer
因为Integer
在上述任何列表中都允许使用 。 - 您可以添加子类
Integer
的实例,因为Integer
在上述任何列表中都允许子类的实例。 - 您不能添加 a
Double
因为foo3
可能指向ArrayList<Integer>
. - 您不能添加 a
Number
因为foo3
可能指向ArrayList<Integer>
. - 您不能添加 ,
Object
因为foo3
可能指向ArrayList<Integer>
。
- 您可以添加 ,
PECS
职业教育学院
Remember PECS: "Producer Extends, Consumer Super".
记住PECS:“生产者扩展,消费者超级”。
"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"- If you need a
List
to consumeT
values (you want to writeT
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.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>
.
“Producer Extends”- 如果您需要 a
List
来生成T
值(您想T
从列表中读取s),则需要使用 声明它? extends T
,例如List<? extends Integer>
. 但是您不能添加到此列表中。“Consumer Super”- 如果您需要使用 a
List
来消费T
值(您想将T
s 写入列表中),您需要使用 声明它? super T
,例如List<? super Integer>
。但是不能保证您可以从此列表中读取什么类型的对象。如果您需要读取和写入列表,则需要完全声明它,没有通配符,例如
List<Integer>
.
Example
例子
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
:
请注意Java 泛型常见问题解答中的这个示例。请注意源列表src
(生产列表)如何使用extends
,目标列表dest
(消费列表)如何使用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));
}
}
Also see How can I add to List<? extends Number> data structures?
回答by Istao
super is a lower bound, and extends is an upper bound.
super 是一个下界, extends 是一个上限。
According to http://download.oracle.com/javase/tutorial/extra/generics/morefun.html:
根据http://download.oracle.com/javase/tutorial/extra/generics/morefun.html:
The solution is to use a form of bounded wildcard we haven't seen yet: wildcards with a lower bound. The syntax ? super T denotes an unknown type that is a supertype of T (or T itself; remember that the supertype relation is reflexive). It is the dual of the bounded wildcards we've been using, where we use ? extends T to denote an unknown type that is a subtype of T.
解决方案是使用一种我们尚未见过的有界通配符形式:具有下限的通配符。语法?super T 表示一个未知类型,它是 T 的超类型(或 T 本身;记住超类型关系是自反的)。它是我们一直使用的有界通配符的对偶,我们在哪里使用 ? 扩展 T 以表示作为 T 子类型的未知类型。
回答by Sai Sunder
Using extendsyou can only get from the collection. You cannot put into it. Also, though superallows to both get and put, the return type during get is ? super T.
使用扩展只能从集合中获取。你不能投入进去。另外,虽然super允许 get 和 put,但 get 期间的返回类型是? 超级牛逼。
回答by Vaibhav Gupta
The generic wildcards target two primary needs:
通用通配符针对两个主要需求:
Reading from a generic collection Inserting into a generic collection There are three ways to define a collection (variable) using generic wildcards. These are:
从泛型集合中读取 插入泛型集合 使用泛型通配符可以通过三种方式定义集合(变量)。这些是:
List<?> listUknown = new ArrayList<A>();
List<? extends A> listUknown = new ArrayList<A>();
List<? super A> listUknown = new ArrayList<A>();
List<?>
means a list typed to an unknown type. This could be a List<A>
, a List<B>
, a List<String>
etc.
List<?>
表示键入为未知类型的列表。这可能是 a List<A>
、 a List<B>
、 aList<String>
等。
List<? extends A>
means a List of objects that are instances of the class A
, or subclasses of A
(e.g. B and C).
List<? super A>
means that the list is typed to either the A class
, or a superclass of A
.
List<? extends A>
表示作为class A
, or实例的对象列表subclasses of A
(例如 B 和 C)。
List<? super A>
表示该列表被输入到A class
或 a 中superclass of A
。
Read more : http://tutorials.jenkov.com/java-generics/wildcards.html
阅读更多:http: //tutorials.jenkov.com/java-generics/wildcards.html
回答by Luigi Cortese
Imagine having this hierarchy
想象一下有这个层次结构
1. Extends
1. 扩展
By writing
通过写作
List<? extends C2> list;
you are saying that list
will be able to reference an object of type (for example) ArrayList
whose generic type is one of the 7 subtypesof C2
(C2
included):
您是说list
将能够引用类型(例如)的对象,ArrayList
其泛型类型是(包括)的 7个子类型之一:C2
C2
- C2:
new ArrayList<C2>();
, (an object that can store C2 or subtypes) or - D1:
new ArrayList<D1>();
, (an object that can store D1 or subtypes) or - D2:
new ArrayList<D2>();
, (an object that can store D2 or subtypes) or...
- C2:
new ArrayList<C2>();
,(可以存储 C2 或子类型的对象)或 - D1:
new ArrayList<D1>();
,(可以存储 D1 或子类型的对象)或 - D2:
new ArrayList<D2>();
,(可以存储 D2 或子类型的对象)或...
and so on. Seven different cases:
等等。七种不同情况:
1) new ArrayList<C2>(): can store C2 D1 D2 E1 E2 E3 E4
2) new ArrayList<D1>(): can store D1 E1 E2
3) new ArrayList<D2>(): can store D2 E3 E4
4) new ArrayList<E1>(): can store E1
5) new ArrayList<E2>(): can store E2
6) new ArrayList<E3>(): can store E3
7) new ArrayList<E4>(): can store E4
We have a set of "storable" types for each possible case: 7 (red) sets here graphically represented
对于每种可能的情况,我们都有一组“可存储”类型:此处以图形方式表示了 7 个(红色)集合
As you can see, there is not a safe typethat is common to every case:
如您所见,并非所有情况都通用的安全类型:
- you cannot
list.add(new C2(){});
because it could belist = new ArrayList<D1>();
- you cannot
list.add(new D1(){});
because it could belist = new ArrayList<D2>();
- 你不能,
list.add(new C2(){});
因为它可能是list = new ArrayList<D1>();
- 你不能,
list.add(new D1(){});
因为它可能是list = new ArrayList<D2>();
and so on.
等等。
2. Super
2.超级
By writing
通过写作
List<? super C2> list;
you are saying that list
will be able to reference an object of type (for example) ArrayList
whose generic type is one of the 7 supertypesof C2
(C2
included):
您是说list
将能够引用类型(例如)的对象,ArrayList
其泛型类型是(包括)的 7 个超类型之一:C2
C2
- A1:
new ArrayList<A1>();
, (an object that can store A1 or subtypes) or - A2:
new ArrayList<A2>();
, (an object that can store A2 or subtypes) or - A3:
new ArrayList<A3>();
, (an object that can store A3 or subtypes) or...
- A1:
new ArrayList<A1>();
,(可以存储 A1 或子类型的对象)或 - A2:
new ArrayList<A2>();
,(可以存储 A2 或子类型的对象)或 - A3:
new ArrayList<A3>();
,(可以存储 A3 或子类型的对象)或...
and so on. Seven different cases:
等等。七种不同情况:
1) new ArrayList<A1>(): can store A1 B1 B2 C1 C2 D1 D2 E1 E2 E3 E4
2) new ArrayList<A2>(): can store A2 B2 C1 C2 D1 D2 E1 E2 E3 E4
3) new ArrayList<A3>(): can store A3 B3 C2 C3 D1 D2 E1 E2 E3 E4
4) new ArrayList<A4>(): can store A4 B3 B4 C2 C3 D1 D2 E1 E2 E3 E4
5) new ArrayList<B2>(): can store B2 C1 C2 D1 D2 E1 E2 E3 E4
6) new ArrayList<B3>(): can store B3 C2 C3 D1 D2 E1 E2 E3 E4
7) new ArrayList<C2>(): can store C2 D1 D2 E1 E2 E3 E4
We have a set of "storable" types for each possible case: 7 (red) sets here graphically represented
对于每种可能的情况,我们都有一组“可存储”类型:此处以图形方式表示了 7 个(红色)集合
As you can see, here we have seven safe typesthat are common to every case: C2
, D1
, D2
, E1
, E2
, E3
, E4
.
如您所见,这里我们有七种安全类型,它们在每种情况下都是通用的:C2
, D1
, D2
, E1
, E2
, E3
, E4
。
- you can
list.add(new C2(){});
because, regardless of the kind of List we're referencing,C2
is allowed - you can
list.add(new D1(){});
because, regardless of the kind of List we're referencing,D1
is allowed
- 您可以,
list.add(new C2(){});
因为无论我们引用的列表类型如何,C2
都是允许的 - 您可以,
list.add(new D1(){});
因为无论我们引用的列表类型如何,D1
都是允许的
and so on. You probably noticed that these types correspond to the hierarchy starting from type C2
.
等等。您可能注意到这些类型对应于从 type 开始的层次结构C2
。
Notes
笔记
Here the complete hierarchy if you wish to make some tests
如果你想进行一些测试,这里是完整的层次结构
interface A1{}
interface A2{}
interface A3{}
interface A4{}
interface B1 extends A1{}
interface B2 extends A1,A2{}
interface B3 extends A3,A4{}
interface B4 extends A4{}
interface C1 extends B2{}
interface C2 extends B2,B3{}
interface C3 extends B3{}
interface D1 extends C1,C2{}
interface D2 extends C2{}
interface E1 extends D1{}
interface E2 extends D1{}
interface E3 extends D2{}
interface E4 extends D2{}
回答by Michael Dausmann
I love the answer from @Bert F but this is the way my brain sees it.
我喜欢@Bert F 的答案,但这就是我的大脑看待它的方式。
I have an X in my hand. If I want to writemy X into a List, that List needs to be either a List of X or a List of things that my X can be upcast to as I write them in i.e. any superclassof X...
我手里拿着一个X。如果我想将我的 X 写入一个列表,该列表需要是一个 X 列表或一个我的 X 可以向上转换的事物列表,即我在 X 的任何超类中写入它们...
List<? super X>
If I get a List and I want to readan X out of that List, that better be a List of X or a List of things that can be upcast to X as I read them out, i.e. anything that extendsX
如果我得到一个 List 并且我想从该 List 中读取一个 X,那么最好是一个 X 的列表或一个在我读出它们时可以向上转换为 X 的事物的列表,即任何扩展X 的东西
List<? extends X>
Hope this helps.
希望这可以帮助。
回答by Sushant
Based on Bert F's answerI would like to explain my understanding.
根据Bert F 的回答,我想解释一下我的理解。
Lets say we have 3 classes as
假设我们有 3 个类
public class Fruit{}
public class Melon extends Fruit{}
public class WaterMelon extends Melon{}
Here We have
这里我们有
List<? extends Fruit> fruitExtendedList = …
//Says that I can be a list of any object as long as this object extends Fruit.
Ok now lets try to get some value from fruitExtendedList
好的,现在让我们尝试从 FruitExtendedList 中获取一些值
Fruit fruit = fruitExtendedList.get(position)
//This is valid as it can only return Fruit or its subclass.
Again lets try
再次让我们尝试
Melon melon = fruitExtendedList.get(position)
//This is not valid because fruitExtendedList can be a list of Fruit only, it may not be
//list of Melon or WaterMelon and in java we cannot assign sub class object to
//super class object reference without explicitly casting it.
Same is the case for
同样是这种情况
WaterMelon waterMelon = fruitExtendedList.get(position)
Now lets try to set some object in fruitExtendedList
现在让我们尝试在 FruitExtendedList 中设置一些对象
Adding fruit object
添加水果对象
fruitExtendedList.add(new Fruit())
//This in not valid because as we know fruitExtendedList can be a list of any
//object as long as this object extends Fruit. So what if it was the list of
//WaterMelon or Melon you cannot add Fruit to the list of WaterMelon or Melon.
Adding Melon object
添加 Melon 对象
fruitExtendedList.add(new Melon())
//This would be valid if fruitExtendedList was the list of Fruit but it may
//not be, as it can also be the list of WaterMelon object. So, we see an invalid
//condition already.
Finally let try to add WaterMelon object
最后让我们尝试添加 WaterMelon 对象
fruitExtendedList.add(new WaterMelon())
//Ok, we got it now we can finally write to fruitExtendedList as WaterMelon
//can be added to the list of Fruit or Melon as any superclass reference can point
//to its subclass object.
But waitwhat if someone decides to make a new type of Lemon lets say for arguments sake SaltyLemon as
但是等等,如果有人决定制作一种新型的柠檬,我们可以说为了争论的缘故,SaltyLemon 作为
public class SaltyLemon extends Lemon{}
Now fruitExtendedList can be list of Fruit, Melon, WaterMelon or SaltyLemon.
现在fruitExtendedList 可以是Fruit、Melon、WaterMelon 或SaltyLemon 的列表。
So, our statement
所以,我们的声明
fruitExtendedList.add(new WaterMelon())
is not valid either.
也无效。
Basically we can say that we cannot write anything to a fruitExtendedList.
基本上我们可以说我们不能向fruitExtendedList 写入任何内容。
This sums up List<? extends Fruit>
这总结 List<? extends Fruit>
Now lets see
现在让我们看看
List<? super Melon> melonSuperList= …
//Says that I can be a list of anything as long as its object has super class of Melon.
Now lets try to get some value from melonSuperList
现在让我们尝试从 melonSuperList 中获取一些值
Fruit fruit = melonSuperList.get(position)
//This is not valid as melonSuperList can be a list of Object as in java all
//the object extends from Object class. So, Object can be super class of Melon and
//melonSuperList can be a list of Object type
Similarly Melon, WaterMelon or any other object cannot be read.
同样,Melon、WaterMelon 或任何其他对象都无法读取。
But note that we can read Object type instances
但请注意,我们可以读取 Object 类型实例
Object myObject = melonSuperList.get(position)
//This is valid because Object cannot have any super class and above statement
//can return only Fruit, Melon, WaterMelon or Object they all can be referenced by
//Object type reference.
Now, lets try to set some value from melonSuperList.
现在,让我们尝试从 melonSuperList 设置一些值。
Adding Object type object
添加对象类型对象
melonSuperList.add(new Object())
//This is not valid as melonSuperList can be a list of Fruit or Melon.
//Note that Melon itself can be considered as super class of Melon.
Adding Fruit type object
添加水果类型对象
melonSuperList.add(new Fruit())
//This is also not valid as melonSuperList can be list of Melon
Adding Melon type object
添加 Melon 类型对象
melonSuperList.add(new Melon())
//This is valid because melonSuperList can be list of Object, Fruit or Melon and in
//this entire list we can add Melon type object.
Adding WaterMelon type object
添加西瓜类型对象
melonSuperList.add(new WaterMelon())
//This is also valid because of same reason as adding Melon
To sum it up we can add Melon or its subclass in melonSuperList and read only Object type object.
综上所述,我们可以在 melonSuperList 中添加 Melon 或其子类,并且只读 Object 类型的对象。
回答by 18446744073709551615
The most confusing thing here is that whatever type restrictions we specify, assignment works only one way:
这里最令人困惑的是,无论我们指定什么类型限制,赋值只能以一种方式工作:
baseClassInstance = derivedClassInstance;
You may think that Integer extends Number
and that an Integer
would do as a <? extends Number>
, but the compiler will tell you that <? extends Number> cannot be converted to Integer
(that is, in human parlance, it is wrong that anything that extends number can be converted to Integer):
您可能认为Integer extends Number
anInteger
可以作为 a <? extends Number>
,但是编译器会告诉您<? extends Number> cannot be converted to Integer
(也就是说,用人类的话来说,任何扩展 number 的东西都可以转换为 Integer 是错误的):
class Holder<T> {
T v;
T get() { return v; }
void set(T n) { v=n; }
}
class A {
public static void main(String[]args) {
Holder<? extends Number> he = new Holder();
Holder<? super Number> hs = new Holder();
Integer i;
Number n;
Object o;
// Producer Super: always gives an error except
// when consumer expects just Object
i = hs.get(); // <? super Number> cannot be converted to Integer
n = hs.get(); // <? super Number> cannot be converted to Number
// <? super Number> cannot be converted to ... (but
// there is no class between Number and Object)
o = hs.get();
// Consumer Super
hs.set(i);
hs.set(n);
hs.set(o); // Object cannot be converted to <? super Number>
// Producer Extends
i = he.get(); // <? extends Number> cannot be converted to Integer
n = he.get();
o = he.get();
// Consumer Extends: always gives an error
he.set(i); // Integer cannot be converted to <? extends Number>
he.set(n); // Number cannot be converted to <? extends Number>
he.set(o); // Object cannot be converted to <? extends Number>
}
}
hs.set(i);
is ok because Integer
can be converted to any superclass of Number
(and not because Integer
is a superclass of Number
, which is not true).
hs.set(i);
可以,因为Integer
可以转换为 的任何超类Number
(而不是因为Integer
是 的超类Number
,这是不正确的)。
EDIT added a comment about Consumer Extends and Producer Super -- they are not meaningful because they specify, correspondingly, nothingand just Object
. You are advised to remember PECS because CEPS is never useful.
EDIT 添加了关于 Consumer Extends 和 Producer Super 的评论——它们没有意义,因为它们相应地指定了nothing和 just Object
。建议您记住 PECS,因为 CEPS 从来没有用处。
回答by Kevin STS
When to use extends and super
何时使用 extends 和 super
Wildcards are most useful in method parameters. They allow for the necessary flexibility in method interfaces.
通配符在方法参数中最有用。它们为方法接口提供了必要的灵活性。
People are often confused when to use extends and when to use super bounds. The rule of thumb is the get-put principle. If you get something from a parametrized container, use extends.
人们经常混淆何时使用扩展以及何时使用超级边界。经验法则是 get-put 原则。如果您从参数化容器中获取某些内容,请使用扩展。
int totalFuel(List<? extends Vehicle> list) {
int total = 0;
for(Vehicle v : list) {
total += v.getFuel();
}
return total;}
The method totalFuel gets Vehicles from the list, asks them about how much fuel they have, and computes the total. If you put objects into a parameterized container, use super.
totalFuel 方法从列表中获取车辆,询问他们有多少燃料,并计算总数。如果将对象放入参数化容器中,请使用 super。
int totalValue(Valuer<? super Vehicle> valuer) {
int total = 0;
for(Vehicle v : vehicles) {
total += valuer.evaluate(v);
}
return total;}
The method totalValue puts Vehicles into the Valuer. It's useful to know that extends bound is much more common than super.
totalValue 方法将 Vehicles 放入 Valuer。知道 extends bound 比 super 更常见是很有用的。
回答by jforex78
You can go through all the answers above to understand why the .add()
is restricted to '<?>'
, '<? extends>'
, and partly to '<? super>'
.
你可以通过上面所有的答案,明白为什么.add()
被限制'<?>'
,'<? extends>'
以及部分原因'<? super>'
。
But here's the conclusion of it all if you want to remember it, and dont want to go exploring the answer every time:
但是如果你想记住它,并且不想每次都去探索答案,这里是所有的结论:
List<? extends A>
means this will accept any List
of A
and subclass of A
.
But you cannot add anything to this list. Not even objects of type A
.
List<? extends A>
这意味着将接受任何List
的A
和子类A
。但是您不能在此列表中添加任何内容。甚至不是类型的对象A
。
List<? super A>
means this will accept any list of A
and superclass of A
.
You can add objects of type A
and its subclasses.
List<? super A>
这意味着将接受任何列表A
和超类A
。您可以添加类型的对象A
及其子类。