概念
假设Orange类是Fruit类的子类,以集合类List为例:
型变: 用来描述类型转换后的继承关系(即协变、逆变和不变的统称)。比如:List是List的子类型吗?答案是No,两者并没有关系,并不能相互读写数据。因此,型变是处理如List(List<? extends Orange>)和List子类型关系的一种表达方式。
协变(covariance)(<? extends T>): 满足条件诸如List是List<? extends Fruit>的子类型时,称为协变。
逆变(covariance)(<? super T>): 满足条件List是List<? super Orange>的子类型时,称为逆变。
不变(invariance)(T): 表示List和List不存在型变关系。
型变
看一个不使用型变的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
List<String> value1 = new ArrayList<String>();
List<Object> value2 = value1;
value2.add(1);
String result = value1.get(0);
|
上面举例说明了在不使用型变的情况下,对泛型数据的操作会面临种种困难,虽然保证了运行时参数类型的安全,却限制了接口的灵活性(编译器检查),比如:如果我们只调用value2(List