java泛型问题,有点小复杂

class Fruit{}
class Apple extends Fruit{}

在Thinking in java这本书的泛型那一章中有这样一个问题,ArrayList类中有一个add()函数,书中说当你指定一个ArrayList<? extends Fruit>时,add()的参数就变成了"? extends Fruit",因此它不会接受任何类型的Fruit。
但是在随后的一节中有这样一个类
class CovariantReader<T>{
T readCovariant(List<? extends T> list){
return list.get(0);
}
}

这个类可以却可以这样CovariantRearer<Fruit> fruit = new CovariantRearer<Fruit>() Fruit a = fruit.readCovariant(Arrays.asList(new Apple())) //可以运行
逻辑上好像是对的,但是总感觉和上面所讲的矛盾,不应该能接受List<Apple>

List<? extends T> 这种写法和List<T> 是一样的,这是一种封装对象时的写法,表示可以list中可以添加T以及继承T的数据,不知到你哪里弄不明白,单单就这个类来看
class CovariantReader<T>{
T readCovariant(List<? extends T> list){
return list.get(0);
}
}
单看这个类表示集合中可以存放任何一种数据类型,追问

class A{
}
class B extends A{
}

List list = new ArrayList();
list.add(new B());
为什么不能向list中添加任何对象了呢,连Object也不行,这是为什么呢,跟上面的例子有什么不同吗?add方法的参数是? extends A

追答

这样写就只能添加A对象或者是A对象的子集对象,,你那个Object是A的父集对象,当然就不能添加了,这就是泛型的作用啊。说了这个语句List list = new ArrayList();和这个语句List list = new ArrayList();是一样的,这个已经声明了list中只能存放A对象,

温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-03-23
继承没学好啊,LZ!!仔细看下Apple跟Fruit他们的关系,子和父关系,老子可以放了,儿子不能放么?追问

。。。。。List不是List的子类,协变性问题,你可以去看看

追答

List不是List的子类,是的,可是list里面装的对象,是什么关系呀?Apple是Fruit的子类!list定义成父类或父接口,添加继承或实现接口的类的对象可以装进去并不暴异常不.fruit.readCovariant(Arrays.asList(new Apple())) 传入这个方法的时候他会自动判断Apple类是否继承Fruit类,是Fruit类的子类大的包容小的,拆箱装箱操作,但是你放在进去的对象不是Fruit的子类的时候报错了!

相似回答