List<? super T>
List<? extends T>
我曾经使用过,但它不允许我向它添加元素,而 确实如此。List<? extends T>
list.add(e)
List<? super T>
网友回答:
想象一下,拥有这种层次结构
通过写作
List<? extends C2> list;
您是说将能够引用类型(例如)的对象,其泛型类型是(包含)的 7 个子类型之一:list
ArrayList
C2
C2
new ArrayList<C2>();
new ArrayList<D1>();
new ArrayList<D2>();
等等。七种不同的情况:
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
对于每种可能的情况,我们都有一组“可存储”类型:此处以图形方式表示 7 个(红色)集
如您所见,并非每种情况都通用的安全类型:
list.add(new C2(){});
list = new ArrayList<D1>();
list.add(new D1(){});
list = new ArrayList<D2>();
等等。
通过写作
List<? super C2> list;
您是说将能够引用类型(例如)的对象,其泛型类型是(包括)的 7 个超类型之一:list
ArrayList
C2
C2
new ArrayList<A1>();
new ArrayList<A2>();
new ArrayList<A3>();
等等。七种不同的情况:
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
对于每种可能的情况,我们都有一组“可存储”类型:此处以图形方式表示 7 个(红色)集
如您所见,这里我们有七种每种情况通用的安全类型:、。C2
D1
D2
E1
E2
E3
E4
list.add(new C2(){});
C2
list.add(new D1(){});
D1
等等。您可能注意到,这些类型对应于从类型开始的层次结构。C2
如果您想进行一些测试,这里是完整的层次结构
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{}
网友回答:
extends
通配符声明意味着其中任何一个都是合法的赋值: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
List foo3
数字
,因为可以指定为包含 .foo3
Number
Number
Integer
foo3
List<Double>
Double
foo3
List<Integer>
List foo3
ArrayList
Integer
foo3
List<Double>
Double
foo3
List<Integer>
Number
foo3
List<Integer>
您不能将任何对象添加到 List<? extend T>
,因为您无法保证它真正指向哪种 List
,因此您无法保证该对象在该列表中
是允许的。唯一的“保证”是你只能从中读取,你会得到一个T或T
的子类。
super
现在考虑 .List <? super T>
通配符声明意味着其中任何一个都是合法的赋值: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
List foo3
Integer
foo3
List<Number>
List<Object>
Number
foo3
List<Object>
对象
或子类的实例(但你不知道是什么子类)。Object
List foo3
ArrayList
Integer
Integer
Integer
Integer
Double
foo3
ArrayList<Integer>
Number
foo3
ArrayList<Integer>
Object
foo3
ArrayList<Integer>
记住PECS:“生产者延伸,消费者超级”。
List
T
T
? extends T
List<? extends Integer>
List
T
T
? super T
List<? super Integer>
List<Integer>
请注意 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));
}
}
另请参阅
如何添加到列表<?扩展数字>数据结构?
网友回答:
我喜欢@Bert F的答案,但这是我的大脑看待它的方式。
我手里拿着一个X。如果我想将我的 X 写入一个列表,该列表必须是 X 的列表或我的 X 可以在我编写它们时被放大到的事物列表,即 X 的任何超类……
List<? super X>
如果我得到一个列表,并且我想从该列表中读取一个 X,那最好是 X 列表或一个在我读出它们时可以向上转换为 X 的事物列表,即任何扩展 X 的东西
List<? extends X>
模板简介:该模板名称为【什么是PECS?和 有什么区别?List super T>List extends T>】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【Java】栏目查找您需要的精美模板。