小弟最近在学习thinking in java,看到了让人欲仙欲死的泛型一章,但是在实验作者给出来的代码时,有个地方看的不是太明白,代码如下
import java.util.*;
public class GenericWriting {
static <T> void writeExact(List<T> list,T item){
list.add(item);
}
//Fruit是父类,Apple继承Fruit
static List<Apple> apples=new ArrayList<Apple>();
static List<Fruit> fruit=new ArrayList<Fruit>();
static void f1(){
writeExact(apples,new Apple());
//[color=red]writeExact(fruit,new Apple()); Error 这就是不明白的一行[/color]
}
static <T> void writeWithWildcard(List<? super T> list,T item){
list.add(item);
}
static void f2(){
writeWithWildcard(apples,new Apple());
writeWithWildcard(fruit,new Apple());
}
public static void main(String[] args){
f1();
System.out.println(apples); //这个输出是我为了测试加的
System.out.println(fruit);
f2();
System.out.println(apples);
System.out.println(fruit);
}
}
按照作者的意思,writeExact()这个方法应该不允许将Apple放置到List<Fruit>中,也就是取消注释,编译器应该直接报错(根据我看了一半的感觉来看,如果无法编译的,作者才会把它注释掉,反之只会进行说明),但是我取消掉注释后,编译器照样运行,而且可以将Apple放到List<Fruit>中,我研究了半天上下文,发现跟上下文要表达的意思不符,所以求牛人讲解一下~~
P.S:俺是小白,所以请各位牛人最好讲的细一点,谢谢~~
------解决方案--------------------
没必要把泛型想得那么深。
泛型就是起到限定一个集合中元素类型的作用。
当一个集合,你只存一种类型数据,你就可以使用泛型了。
就这么简单。别想的太深。实际开发中知道这些就足够了。
------解决方案--------------------
楼主不明白的那个语句,应该换成
- Java code
writeExact(apples,new Fruit());
------解决方案--------------------
编译之后你的T均为object,经过反编译:
- Java code
static void writeExact(List list, Object obj) { list.add(obj); } static List apples = new ArrayList(); static List fruit = new ArrayList();