java 协变 逆变 不可变ITeye - 众发娱乐

java 协变 逆变 不可变ITeye

2019-01-10 21:40:19 | 作者: 海昌 | 标签: 协变,增加,办法 | 浏览: 2797

参阅:http://blog.csdn.net/zero__007/article/details/52245475

文章没转过来,下面是个人定论:
协变:子类的办法返回值可所以父类的子类型。可是办法形参不能是父类办法形参的子类型。
逆变:协变的反类型。
协变的使用是多态和里氏替换准则。

List Number 并不是List Integer 的父类型,两者没有任何关系。

List Number d = new ArrayList Number //能够增加Number及Number的任何子类元素

List ? extends Number d2 = new ArrayList Integer //? extends规则了上限。不能增加除了null之外的任何元素。由于d2详细使用的list目标可所以Integer也可所以Float、Double等,所以不能增加确认的Number元素。

List ? super Number d3 = new ArrayList Number或许Object //? super规则了下限,能够增加Number的任何子类,可是不能增加Number的父类。

所以d2和d3中能不能增加元素、增加什么类型的元素要害看和后边详细的调集目标有没有或许存在抵触,假如存在抵触那必定就不能增加元素了。

什么时分用? extends,什么时分用? super,有个PECS规律,即producer extends, consumer super。在一个调集是数据提供方就用? extends,是数据消费方就用? super。如代码:
public static T void copy(List ? super T dest, List ? extends T src) { 
 int srcSize = src.size(); 
 if (srcSize dest.size()) 
 throw new IndexOutOfBoundsException("Source does not fit in dest"); 
 if (srcSize COPY_THRESHOLD || 
 (src instanceof RandomAccess dest instanceof RandomAccess)) { 
 for (int i=0; i srcSize; i++) 
 dest.set(i, src.get(i)); 
 } else { 
 ListIterator ? super T di=dest.listIterator(); 
 ListIterator ? extends T si=src.listIterator(); 
 for (int i=0; i srcSize; i++) { 
 di.next(); 
 di.set(si.next()); 

这也就通知咱们,在自界说带list泛型办法的时分,假如这个办法是要消费形参传入进来的数据,这时形参是数据提供方,要界说成list ? extends T src,假如办法是要发生数据并传给形参,这时形参是数据消费方,要界说成list ? super T dst。
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表众发娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章