任何人都可以解释为什么我们在?
泛型中使用Collection
。
例如:
List<? extends Number> numberlist;
List<? super Integer> numberlist;
答案 0 :(得分:25)
通配符引入了如何使用集合的限制。
例如,对于List<? extends Number>
,我无法在列表中添加新元素。这是因为我所知道的是列表是Number
的某种子类型,但我不知道实际的子类型是什么(所以我怎么知道要添加什么?)。例如,请使用以下代码:
public void doSomethingWith(List<? extends Number> numbers) {
numbers.add(Integer.valueOf(0)); // Won't compile
}
这不会编译,因为这些方法调用都是合法的:
doSomethingWith(new ArrayList<Integer>());
doSomethingWith(new ArrayList<Double>());
可以做的是从列表中读取元素:
// This will all compile
public void doSomethingWith(List<? extends Number> numbers) {
for (Number number : numbers) {
// Do something with number
}
// OR
Number number = numbers.get(0);
// OR
Number number = numbers.remove(0);
}
调用get
之类的方法会返回某种Number
,我们知道因为? extends Number
而导致事实,因此我们可以将其视为阅读目的。< / p>
另一方面,List<? super Integer>
具有完全相反的结果。我不能再从列表中读取,但我可以写信给它。我知道无论?
是什么,它肯定是Integer
的超类,所以列表的具体类型肯定会接受Integer
值。例如:
public void doSomethingWith(List<? super Integer> integers) {
integers.add(Integer.valueOf(0));
}
该代码完全合法。但是,如果要从列表中读取,唯一的方法是使用Object
,因为其他任何需要强制转换(需要知道其具体类型):
for (Object obj : integers)
// OR
Object obj = integers.get(0);
// OR
Object obj = integers.remove(0);
真正发生的事情
这是实际发生的事情。当您指定? extends Number
时,您将使用将元素作为参数无法使用的任何方法。实际上,如果您尝试使用List<? extends Number>
上的Ctrl + Space在Eclipse中自动完成代码,则会在null
方法等中显示add
作为参数的类型。同时,返回元素的所有方法都保证至少返回某种Number
,尽管你不确切知道它实际上是哪个Number
的子类。
当您指定? super Integer
时,您将使用采用元素作为参数的任何方法保证他们接受Integer
值(以及{的子类{1}}。这允许您调用Integer
之类的方法,因为您知道它们会接受add
类型。同时,所有返回元素的方法只能保证返回某些,但我们不知道是什么,所以返回元素的所有方法都只保证返回{{ 1}}。
PECS是记住这一点的优秀首字母缩略词,它意味着“ P roducer E xtends, C onsumer S upers”。这意味着如果您希望列表为您提供某些内容,那么它就是生产者,您应该使用Integer
。如果您希望列表接受来自您的内容,那么它就是消费者,因此您使用Object
。有关详情,请参阅this answer。
但是如果我有一个没有边界的通配符怎么办?
两者兼得! extends
限制您调用将泛型类型作为参数的方法,而会导致返回泛型类型的所有方法返回super
。这是因为我们不知道这种类型是什么。例如,<?>
中的所有这些分配都是合法的:
Object
等等。
答案 1 :(得分:2)
它是一个通配符。 ?表示从数字继承或者是Integer类的超类的任何类都可以工作。希望这可以帮助。 :)
答案 2 :(得分:2)
当您在扩展和超级之间学习通配符和差异时,只需记住PECS即可。这条规则的所有内容都非常简单易记。
答案 3 :(得分:1)
?
用于在使用泛型时定义wild cards。
示例中的语句告诉List接受Number
答案 4 :(得分:1)
?
表示任何课程
? extends MyClass
表示MyClass或MyClass本身的任何子类。
答案 5 :(得分:1)
以下是我要说的:
List<? extends Number> numberlist; //Any class that is extended from Number class, for example Integer, BigInt, ... may come
List<? super Integer> numberlist; //Any class that Integer class is extended from. Here for example Number may come
因为:
Integer extends Number{
}
答案 6 :(得分:0)
List<? extends Number>
和List<Number>
都允许添加例如整数,但是:
使用List<Number>
,你可以放入整数和其他任何“是”数字。使用List<? extends Number>
,您只能输入一个具体的运行时类型。是它的整数,那么你就不能添加另一种也是数字的类型。