为何无法将Vehicle超类Nonlife存入Collection<? super Vehicle>容器?
首先得明确Collection<? super Vehicle>这个通配符的真实含义:它表示这个集合的元素类型是Vehicle的某个超类(包括Vehicle本身),但编译器无法确定具体是哪一个超类。
为什么不能添加Nonlife对象?举个实际场景的例子:如果有人调用你的appendNolife2Collection方法时,传入的是一个Collection<Vehicle>(这完全符合Collection<? super Vehicle>的类型要求),但Collection<Vehicle>只能容纳Vehicle及其子类对象,你往里面加Nonlife对象显然会造成类型不兼容。编译器为了从根源上保证类型安全,就会阻止这种可能破坏类型系统的操作。
简单总结规则:? super T允许你添加的是T及其子类的对象——因为不管这个集合的实际类型是T的哪个超类,T和它的子类肯定都是这个超类的子类,所以能安全存入;但T的父类就不行,因为集合的实际类型可能就是T本身,这时父类对象无法存入。
解决方案
如果你确实需要往集合中存入Nonlife对象,你需要把方法的参数类型调整为Collection<? super Nonlife>,这样编译器就知道这个集合的元素类型是Nonlife的某个超类,Nonlife、Vehicle、SUV都可以安全存入:
public static void appendNolife2Collection(Collection<? super Nonlife> coll) { coll.add(new Nonlife()); // 现在编译通过 coll.add(new Vehicle()); // 依然可以添加Vehicle coll.add(new SUV()); // 依然可以添加SUV }
或者,如果你的业务场景中这个集合明确就是用来存放Nonlife及其子类的,直接使用Collection<Nonlife>作为参数类型也是更清晰的选择:
public static void appendNolife2Collection(Collection<Nonlife> coll) { coll.add(new Nonlife()); coll.add(new Vehicle()); coll.add(new SUV()); }
这样调整后,你的代码就能实现存入Nonlife对象的需求,同时保证类型安全。
内容的提问来源于stack exchange,提问作者cmpltrtok

