- 对于类型通配符
import java.util.ArrayList;
import java.util.List;
class Fruit{}
class Apple extends Fruit{}
class Orange extends Fruit{}
public class Main {
public static void main(String[] args) {
List<? extends Fruit> fruits;
List<Apple> apples = new ArrayList<>();
List<Orange> oranges = new ArrayList<>();
apples.add(new Apple());
oranges.add(new Apple()); //编译错误
fruits = oranges;
/*这和上一个注释掉的语句作用相同,因此这里List<? extends Fruit> fruits不能添加Apple对象*/
fruits.add(new Apple()); //编译错误
/*这和上上一个注释掉的语句作用相同,因此这里List<? extends Fruit> fruits甚至不能添加Object对象*/
fruits.add((Object)new Apple()); //编译错误
/*任何参数里涉及泛型的函数由于安全问题都无法正常使用,get方法没有泛型,返回时Object,因此可以正常使用*/
fruits.get(1);
}
}
对于`List<? extends Fruit> fruits,应当将其解读为
具有任何从Fruit继承的类型的列表
而不应该是
这个List将持有任何类型的Fruit
- 对于超类型通配符
import java.util.ArrayList;
import java.util.List;
class Fruit{}
class Apple extends Fruit{}
class Orange extends Fruit{}
class Jonathan extends Apple{}
public class Main2 {
public static void main(String[] args) {
List<? super Apple> fruits;
List<Apple> apples = new ArrayList<Apple>();
fruits = apples;
/*fruits 的基类是Apple,因此可以添加任何Apple类型及其子类,无法添加Object */
fruits.add(new Apple());
fruits.add(new Jonathan());
list1.add(new Object()); //编译错误
/*get函数正常,原理相同*/
fruits.get(1);
}
}
-
总结
出于类型安全考虑
- 对于
List<? extends Apple> apple
,不能使用add()方法添加任何对象 - 对于
List<? super Apple> apples
,可以使用add()方法添加Apple对象及其子类对象
- 对于
参考资料:Java编程思想 P390-P393
如有错误还请指正