以前可能会以不同的格式提出这个问题,但我找不到合适的答案。
这些代码之间的区别是什么:
第一个代码
ArrayList<? super Number> list=new ArrayList<>(Arrays.asList(1));
第二个代码
ArrayList<? extends Number> list=new ArrayList<>(Arrays.asList(1));
两个声明都编译。请证明前者编纂的原因。它显示Integer扩展Number和Integer超级数。
修改::
我期待的答案是:
new ArrayList(Collection<? extends E>)
因此他们都编译。
以这种方式,这不是一个重复的问题,因为所提到的答案没有描述这一点。
答案 0 :(得分:0)
它们都以相同的方式执行,但编译器会阻止它们以不同的方式进行编译。
public class NewClass {
private List<? super Number> supers;
private List<? extends Number> extenders;
public NewClass() {
supers = new ArrayList<>();
extenders = new ArrayList<>();
}
public void addSupers() {
supers.add(new Integer("5"));
}
public void addExtenders() {
// This won't compile
extenders.add(new Integer("5"));
}
public void getSupers() {
// this won't compile
Number number = supers.get(1);
}
public void getExtenders() {
Number number = extenders.get(1);
}
}
在supers
添加案例中,您可以安全地添加Integers
,因为Integers
拥有超级Number
。您无法在extenders
情况下执行此操作,因为扩展程序包含 Number
的特定子类,在这种情况下由通配符确定。简而言之,通常假定extenders
项包含所有相同的Number子类。
在supers
获取案例中,您无法安全地提取Number
,因为对于某些类型,可能不是Numbers
,而是Number
的超类,所以&#34;向下演员&#34;很危险但是,在extenders
方案中,所有内容都被确保为Number
的子类,因此可以安全地将它们转换为Number
。
答案 1 :(得分:0)
<? super Number>
表示该类型是Number
的任何超类。
<? extends Number>
表示该类型是Number
的任何子类。
他们会编译到相同的东西,但这取决于您实际使用List
的类型。
如果你有一个List<? super Number>
,你可以把任何Number
放进去,但编译器不能保证你得到的东西是{{1} }}。如果您有Number
,那么您获得的任何内容都肯定会从List<? extends Number>
继承。
如果尝试将Number
传递给期望List<? super Number>
的方法,编译器将会反对,因为前者可能包含的内容不是List<? extends Number>
。
如果尝试将Number
传递给期望List<? extends Number>
的方法,编译器将会反对,因为前者无法接收后者可以使用的元素。