2.4 The Get and Put Principle
Get and Put Principle:
用于取对象的泛型集合,声明为 <? extends T>
用于存对象的泛型集合,声明为 <? super T>
如果同时存取,那么还是老老实实的用< T>吧
注意:
void put(List<? extends Number> nums){
nums.add(?)
}
上面代码中'?'处只能放入null
值,因为你并不能确定nums
具体是什么类型的List
,可能是List< Integer>
也可能是List< Double>
等,而它们共有的add方法一个是add(Integer i)
另一个是add(Double d)
,因此只能放入null
。
`List<? extends T>`实际使用中,只能是一种类型的集合,而不是说这个集合中的对象类型从`?`到 `T`,这里要好好理解这句话。
2.5 Arrays
看如下代码:
package java_generics_collections.chap2;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created by jintaox on 2016/3/9.
*/
public class Test_2_5 {
@Test
public void test01() {
Integer[] ints = new Integer[]{1, 2, 3};
Number[] nums = ints;
nums[2] = 2.3;//runtime error :java.lang.ArrayStoreException: java.lang.Double
}
@Test
public void test_02() throws Exception {
List<Integer> ints = new ArrayList<>();
// List<Number> nums = ints;// compile error
}
}
java中规定,数组是协变的,即如果S是T的字累型,那么S[]是可以替换T[]的,即在任何需要T[]的地方传入s[]是没问题的。
但是泛型不是协变的,前面也说了List< S> 不能替换List< T>。java通过<? extends T>实现协变。
同时,java通过<? super T> 实现逆变(其实,协变逆变从前面阅读到这里应该也明白了),而数组是不支持逆变的。也即,java没有提供对泛型数组的支持。
泛型泛型,就是个泛指,就是让你忽略具体类型的,对这些对象做一系列操作。因此,泛型也就是更高的一种抽象层次,唉,随便说说,也许理解透彻了,别人也就更容易理解了。