java 泛型 协变 逆变,泛型super和extend

  java 泛型 协变 逆变,泛型super和extend

  00-1010什么是常数,什么是协变,什么是逆变扩展和超?你用扩展还是超级,要了解协变与逆变,首先要引入:?

  根据利斯科夫的替换原理,如果C是P的子类,那么P可以替换C,即P P=new C();c继承自p,记为c p。

  00-1010如果F是常数,当C=P时,那么F(C)和F(P)没有继承关系。

  例如,除了整数是数字的子类,根据利斯科夫替换原理

  Number number=新整数(1);//正确但是这样写的话会报错。

  list number list=new ArrayListInteger(1);//错误虽然Number和Integer之间有继承关系:Integer Number,但是在Java中,泛型默认不变,所以也可以看出ListNumber和ListInteger之间没有继承关系。

  00-1010如果F是协变的且当C=P时,则F(C)=F(P)

  Java 提供了一个extends来将不变转为协变,例如:

  列表?extends Number list=new ArrayListInteger(1);///此时更正列表吗?Endsnumber可以看作是ArrayListInteger的父类。

  ?Extend Number可以看作是一个类型范围,代表Number的一个子类。

  默认情况下,数组是协变的。

  Number[] numbers=新整数[3];

  00-1010如果F反转,当C=P时,则F(C)=F(P)

  Java 提供了一个super来将不变转为协变,例如:

  列表?超级数list=new ArrayListObject(1);///此时更正列表吗?超级数可以看作是ArrayListObject的父类。

  

目录

首先,我们看看Collection.add的实现:

 

  公共接口ListE扩展collection E { boolean add(E E);}下面代码将会报错??Endsnumber与整数类型不匹配。

  列表?extends Number list=new ArrayListInteger();//correct list . add(integer . value of(1));//错误首先,调用add方法时,泛型e自动变成?扩展号码

  第二行给出一个错误,也就是说?Endsnumber不是Integer的父类。你想把名单放在这里吗?Endsnumber是ArrayListInteger的父类。

  ?EndsNumber可以看作是一个类型范围中的一个类型,代表Number的一个子类,但不清楚是哪个子类。可能是Float,Short或者是Integer的子类(Integer是被final修改的,所以不能有子类。这只是假设的情况)。它只决定了它的上界是数,而不是它的下界(有可能存在吗?扩展NumberInteger),所以呢?扩展数不是整数的父类

  将上面代码稍做修改就正确了:

  列表?超级数list=new ArrayListObject();//correct list . add(integer . value of(1));//正确首先因为倒装句,List?超级号是ArrayListObject的父类,第一行是正确的。

  二线:超级数是Integer的父类因为:Super Number表示Number的父类,可以是Serializable,也可以是Object,但无论哪种情况,Number的父类都必须是Integer的父类,所以第二行是正确的。

  

什么是不变

java.util.Collections的copy方法(JDK1.7)给了我们答案:

 

  public static T void copy(List?超级目的地,列表?扩展T src){ int src size=src。size();if (srcSize dest.size())抛出新的IndexOutOfBoundsException( Source不适合dest’);if(src size COPY _ THRESHOLD (src instance of random access dest instance of random access)){ for(int I=0;isrcSizei)目标集合(I,src。get(I));} else { ListIterator?超级T di=dest。列表迭代器();ListIterator?扩展T si=src。列表迭代器();for(int I=0;isrcSizeI){ di。next();迪。设置(si。next());} }}要从泛型类取数据时,用延伸;要往泛型类写数据时,用超级;既要取又要写,就不用通配符(即延伸与极好的都不用)私有静态E E getFirst(List?扩展e列表){返回列表。get(0);}私静E void set first(List?超级E list,E first element){ list。添加(第一个元素);} public static void main(String[]args){ list integer list=new ArrayListInteger();setFirst(list,1);number number=get first(list);}到此这篇关于爪哇泛型之协变与逆变及延伸与极好的选择的文章就介绍到这了,更多相关爪哇泛型内容请搜索盛行信息技术以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行它!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: