软件构造——Java中的型变与泛型

型变:当子类型关系出现在更加复杂类型中时,新类型中有着怎样的类型关系br> 如:
Cat是Animal的子类,那么List 和List有什么关系/p>

型变有如下三种情况:
Covariant(协变): 保持子类型关系List是List的子类
Contravariant(逆变):反转了子类型关系 ,如List是List的子类
Invariant(不变): 没有子类型关系,如List nor 和List均不具备父类型与子类型关系
图示是子类型中重写父类型方法,参数和返回值的协变逆变情况:

软件构造——Java中的型变与泛型可以得到如下输出:
软件构造——Java中的型变与泛型
软件构造——Java中的型变与泛型输出
软件构造——Java中的型变与泛型

具有限定类型下的list操作
List是 List<extends Animal>的子集
1.对于类型 List<extends Animal>,调用一个返回Animal类型(或子类型)的方法(如:T get(int pos))是安全的, 因为compiler知道这个List中的任何对象至少具有Animal类型(或子类型),可以完成类型转换。
2.但调用类似add(E e)的方法则不安全,类型擦除机制会导致运行时可以往animals中储存各种类型的对象。因此,Java此时禁止了List中所有具有泛型输入参数的方法,如:add(T item)

软件构造——Java中的型变与泛型
List是 List<super Cat>的子集
1.对于List中的 T get(int pos)方法,当指定类型是“super Cat”时, get方法的返回类型就变成了“super Cat”, 即返回类型可能是Cat或者Cat的基类型,compiler无法确定具体类型,因此拒绝调用任何返回类型为T的方法(除非是读取为Object类)
2.但调用类似add(E e)的方法则安全, 传入Cat及其子类(WhiteCat)是安全的, 因为compiler知道这个List包含的是Cat或Cat的基类对象。因此,Java此时禁止了List中所有具有泛型返回类型的方法,如:get()
软件构造——Java中的型变与泛型
可得到输出:
软件构造——Java中的型变与泛型

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91508 人正在系统学习中

来源:lll_90

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年5月19日
下一篇 2019年5月19日

相关推荐