Java Generics and Collections-2.3
2.3 Wildcards with super
这里就直接拿书上的例子好了,这是Collections
里面的一个方法:
public static <T> void copy(List<? super T> dst,List<? extends T> src){
for(int i = 0; i < src.size(); i++){
dst.set(i,src.get(i));
}
}
其中<? super T>
表示T以以及T的父类,java的泛型规定了
如List<? super T>
是List< T>
的超类。
上面的方法有可能会有如下几个变种(通过这几个变种来解释上面这个方法):
1, `copy(List< T> dst, List<? extends T> src)`
2, `copy(List< T> dst, List< T> src)`
3, `copy(List<? extends T> dst, List< T> src)`
4, `copy(List<? extends T> dst, List<? extends T> src)`
5, `copy(List<? super T> dst, List< T> src)`
6, `copy(List< T> dst, List<? super T> src)`
7, `copy(List<? super T> dst, List<? super T> src)`
8, `copy(List<? super T> dst, List<? extends T> src)`
唉,其实写这些就是为了说明java泛型的使用 ,就是让它自圆其说罢了,这仅仅是java的泛型规范,人家就这么设计的,咱们就这么用。
1,我们把dst限制死了,如T为Number,那么dst只能是List< Number> src可以是List< Integer> or List< Double> ...不够generic(哈哈,不够泛型)
2,同第一个,dst,src都限制死了,这根本不generic!!!
3,这是错误的,比如dst为List< Integer>, src为List< Number>,如
```java
List< Integer> dst = new ArrayList<>();
List< Number> src = Arrays.asList(1,2,3.4);
copy(dst,src)//compile error,你不能向List< Integer>里面放 3.4
```
4,看起来挺正常,实际上只有前后类型一样使,即情况2时,才能正常工作
5,不够generic,但是一定正确,因为T一定是<? super T> 的子类型,实际上和1差不多
6,当且进档src也是List< T>的时候才正确,运行出错
7, 4的另一个版本,当且仅当类型相同时才能编译通过
8,正确,generic!!!
为什么8是最generic的呢? 其实你看到这里自己就明白了(这里面是有规律的,而且以后学Scala的协变,逆变即+T,-T时,这是基础)。
加油,我要做技术专家。