java 泛型
这篇文章主要记录java 泛型中的协变,逆变情况。
在kotlin 中 泛型用out in 表示协变,逆变。在java中 泛型用
? extends Object // 表示 协变
? super Object // 表示 逆变
协变 :泛型不可以作为参数,只能作为返回值
初始化时,可以用子类初始化。例:
List<? extends Fruit> outFruits = new ArrayList<Orange>()
逆变:泛型不可以作为返回值,不能作为参数。
初始化时,可以用父类初始化。例:
List<? super Fruit> inFruits = new ArrayList<Object>()
代码片段:
public void test() {
// Collection out 协变 只能作为返回结果,无法作为参数 可以用
//@UnsafeVariance修饰 作为参数,告诉编译器不改变泛型
//Comparable in 逆变 只能作为参数,无法作为返回结果
List<Orange> oranges = new ArrayList<>();
List<Fruit> fruits;
// fruits = oranges; 编译不通过
fruits = new ArrayList<>();
fruits.add(new Orange());
fruits.add(new Banana());
Fruit fruit = fruits.get(0);
List<? extends Fruit> outFruits;
outFruits = oranges; // 编译通过,认为List<Orange>为其子类型 协变
outFruits = new ArrayList<>();
// subFruits.add(new Orange()); // 编译器无法确定outFruits添加的泛型是什么,所以无法作为参数
Fruit fruit1 = outFruits.get(0);
List<? super Fruit> inFruits;
inFruits = new ArrayList<Object>();
inFruits.add(new Orange());
inFruits.add(new Banana());
inFruits.add(new Fruit());
Object object = inFruits.get(0); // 逆变 编译器无法确定inFruits返回的泛型是什么,所以无法作为返回值
}