看看这两个例子:
void printCollection(Collection<Object> c) {
for (Object e : c) {
System.out.println(e);
}
}
VS
void printCollection(Collection<?> c) {
for (Object e : c) {
System.out.println(e);
}
}
这两者有什么区别?我读到第二个例子更强大。但那是为什么呢?您无法将哪个参数传递给方法1,您可以将其传递给方法2?
答案 0 :(得分:3)
泛型aren't covariant。换句话说,Collection<String>
不是Collection<Object>
,即使String
是Object
。使用第一个签名,我将无法打印List<String>
例如。
通用通配符有助于表达协方差(如您的示例所示)和逆变。 Collection<?>
是Collection<? extends Object>
的缩写,意思是“某个特定的,未知类型的集合,是Object
”。因此,我们无法向此类集合添加除null
之外的任何内容,因为我们无法保证添加的对象的类型有效。
以下是使用通配符表示逆差的示例:
void populateCollection(Collection<? super Integer> c) {
for (int i = 0; i < 10; i++) {
c.add(i);
}
}
我可以将Collection<Object>
,Collection<Number>
或Collection<Integer>
传递给此方法,因为它被视为Integer
的使用者。在您的示例中,该集合是Object
的生成器。有关通配类泛型类型的“生产者”和“消费者”之间的区别,请参阅此文章:What is PECS (Producer Extends Consumer Super)?