`

Java通配符释疑

 
阅读更多

 

泛型通配符:

例子:

interface AA{}

class BB{}

class A1 extends BB implements AA{}

class B1 extends A1{}

 

List<? extends BB> list = new ArrayList<A1>();

//list.add(new A1()); A1继承BB,但这里会编译报错The method add(capture#1-of ? extends BB) in the type List<capture#1-of ? extends BB> is not applicable for the arguments (A1)

List<? extends BB> list0 = new ArrayList<B1>();

list = list0;

解析:

list.add(new A1())之所以报错是因为不能确定list中的元素是什么类型,虽然此时它的确指向的是new ArrayList<A1>(),但编译器还没有智能到这种程度,知道list当前的元素类型。

List<? extends BB>只是一种引用声明,声明引用的List中的元素类型是继承BB的,但并不确定是何种类型(capture#1-of ? extends BB),所以list = list0并不会报错,

因为list和list0当中的元素都是继承BB的,符合(capture#1-of ? extends BB)的定义声明

 

List<? super B1> list2 = new ArrayList<A1>();

List<? super A1> list3 = new ArrayList<BB>();

//list3 = list2; //编译报错 Type mismatch: cannot convert from List<capture#2-of ? super B1> to List<? super A1>

list2 = list3;

解析:list2不能添加A1类型元素,因为A1是B1的父类,而list3可以添加A1类型元素,因此将list2赋给list3不正确。(add只能add与super同等级的或者为该等级子类的类型,尽管B1的直接超类就是A1,也不能添加A1类元素,只能认为编译器认为B1有可能实现不同的接口,譬如I1,单I1跟A1是没有继承关系的,所以如果集合是I1类型,那添加A1类型的元素肯定是错的)

list2=list3似乎有些别扭,因为list2的元素类型是super B1,即它可能是A1,而list3的元素类型是super A1,即它可能是BB,而将list3赋给list2似乎是将父类元素BB强转为A1,

这应该是报错才对,但我们要回到之前讨论的List<? super B1> 的意义是什么,它只是一种引用声明,声明引用的List的元素类型是super B1的(capture#1-of ? super B1)

至于是什么类型并不确定,它可以动态指向任何元素类型super A1的List。以下赋值声明也正确:

List<? super B1> list4 = new ArrayList<BB>(); //BB是B1的祖辈元素

 

List<? super B1> list2 = new ArrayList<A1>();

//list2.add(new A1()); 编译报错The method add(capture#1-of ? super B1) in the type List<capture#1-of ? super B1> is not applicable for the arguments (A1)

解析:

list2的元素实体明明是用了装A1类型的,但添加A1却报错,这是因为List<? super B1>也可能指向new ArrayList<B1>(),此时直接添加父类元素A1当然报错了

 

总结:

1.List<? super AA> list2 = new ArrayList<AA>();//List<? super AA> list2 = new ArrayList<B1>();这个声明会报错

2.list2.add(new B1());

1和2要的时机是不同的,1是声明,2是往堆内存添加实际对象。

声明时创建的集合泛型类型要直接符合通配符的父子声明;

添加时看是否会存在一种符合通配符的类型A(不用看实际指向的堆内存存的是什么类型的数据),添加的元素类型与类型A不兼容,若无则可添加该类型元素。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics