回答你的问题。
声明ArrayList不等于ArrayList。即使Integer
是从Object
类型层次结构中提供的。
要记住重要的一点是,当你声明Collection<String> myStrings
,你告诉编译器,该变量myString
可以分配指一经String
类型创建和收藏集是唯一的类的实例。
Collection<Object> myObjects;
myObjects = new ArrayList<String>(); //Exception
myObjects = new HashSet<String>(); //Exception
myObjects = new HashSet<Object>(); //Valid
myObjects = new ArrayList<Object>(); //Valid
myObjects = new ArrayList<Integer>(); //Exception
为了解决这样的问题,JAVA提供一套Wildcars,使您可以通过这一点。
有三种类型的支持各种variances的卡。
<? extends T> - Covariance
<? super T> - Contravariance
<?> - Invariance/
有关它们的规则称为PECS
我们要消耗列表元素,删除你应该使用协方差的编译错误。
Collection<? extends Object> myObjects;
myObjects = new ArrayList<String>(); //Valid
myObjects = new HashSet<String>(); //Valid
myObjects = new HashSet<Object>(); //Valid
myObjects = new ArrayList<Object>(); //Valid
myObjects = new ArrayList<Integer>(); //Valid
由于Java中的每个类是从对象传递这样<? extends>
在功能上等于<?>
,而这正是rgettman提出的答案
Java中的集合框架支持与generics。您应该熟悉它们才能从框架中充分受益。
一种不同的方式来解决是是从通用的方法,这样有利于:
public static <T> void printList<Iterable<T> iterable) {
for(T element : iterable){
System.out.printf("%s ",element);
}
System.out.println();
}
为什么静态的?
对静态方法的调用速度更快,此方法与任何类成员都没有关系。
什么是?
这是generic method的声明。它允许你定义泛型参数的值。 Java非常敏锐,它可以自己提取版本7中的大多数情况。
如果您使用Iterable<String>
调用方法,那么如果Iterable接着是'Integer',则T的值将是String
。
为什么可以迭代?
Iterable是一个简单的界面,允许您使用for-each look。这意味着您将能够遍历类定义实现它的所有对象。
为什么printf?
printf函数使用Formatter,从它的好处有两个 - 在当element
实例分配与空的情况下,你不会得到,如果你把它o.toString()
会出现空指针异常。
缺什么?
在那个实现中仍然缺少两件事 - 输入验证 - 正确的输出格式,将用昏迷分隔元素。
这将暗示使用原始类型,并销毁此类中的所有泛型类型检查... – Marco13