//类的继承结构
class Fruit{}
class Apple extends Fruit{}
class Jonathan extends Apple{}
public class SuperTypeVildcards {
static void writeTo( LIst<? super Apple> apples){
apples.add(new Apple());
apples.add(new Jonathan())
// Error
apples.add(new Fruit());
}
}
《Java编程思想》有关这段代码是这样描述的:参数Apple是Apple的某种基类型的List,这样你就知道向其中添加Apple或Apple的子类型是安全的。
而根据理解 List< ? super Apple> 表示的应该是List中持有的是Apple的基类。根据我的想法,第8,9行应该是错误的,而第11行才是正确的。
看了半天也不太懂书里面关于边界的描述。希望能得到解答
------解决思路----------------------
举个例子:
假如有一个继承体系:Object <- Plant <- Fruit <- Apple <- Jonathan,通配符是? super Apple,Apple是下界,?是Apple的某种父类型,那么Apple及其子类一定是?类型, 所以你可以加入Apple和Jonathan类型,但是你不可以加入Fruit,因为通配符只是说是Apple的某种父类型,你怎么知道是Fruit还是Plant还是Object?
行了,自己也快晕了...
------解决思路----------------------
接着楼上补充一下,? super Apple 表明泛型是Apple或者Apple的父类,所以能够将Apple的子类安全的添加到List中(因为子类的引用能够安全的隐式转换为父类),但是,编译器没法推断出泛型和Fruit的关系,泛型有可能是Fruit的子类,不能隐式的将父类的引用转换为子类,所以编译器会报错。
------解决思路----------------------
怎么你觉得Apple和 Jonathan不是Apple类型吗?
Java的泛型是这样子实现的,先把所有对象都当作Object存起来,取出来的时候再转成相应的类型。
所以这个例子中,应该理解为所有可以转型为Apple的类,也就是Apple和他的子类。只有这些类才能放进这个容器中,当他们取出来的时候统统转为Apple类。所以fruit对象,是不能添加进去的。
如果理解成存放Apple的父类,那么系统将会不知道在取出对象的时候应该转为什么类型,因为他的父类是不确定的,(?)。
再往后,书里应该说<? extends T>的问题,恩同样的道理,你仔细体会一下,想想java泛型怎么实现的