Java逆变(Covariant)和协变(Contravariant)
1. 定义
逆变和协变描述的经过类型变换后的类型之间的关系。假如A和B表示类型,f表示类型变换,A ≤B表示A是B的子类型,那么
- 如果
A ≤B,f(A) ≤f(B),那么f是协变 - 如果
A ≤B,f(B) ≤f(A),那么f是逆变 - 如果两者都不是,那么f不变
这里的子类型并非是面向对象中继承关系中的子类型,它更多的是描述两个类型之间的兼容性。
2. 实例:泛型
考虑一个例子,假如f(A) = List<A>,且List声明如下:
class List<T> { ... }
那么f是逆变,还是协变,又或者是不变?如果是协变意味着List<String>是List<Object>的子类型,如果是逆变意味着List<Object>是List<String>的子类型:
ArrayList<String> strings = new ArrayList<Object>(); // error
ArrayList<Object> objects = new ArrayList<String>(); // error
在Java中显然两者都不成立,所以说f是不变,且f表示泛型,即Java泛型是不变。
2. 实例:数组
再举个例子,假如f(A) = A[], 那么f是逆变,还是协变,又或者是不变?如果是协变意味着String[]是Object[]的子类型,如果是逆变意味着Object[]是String[]的子类型:
Object[] objects = new String[1];
可以看出,在Java中数组是协变。
Java逆变(Covariant)和协变(Contravariant)的更多相关文章
- Java 逆变与协变的名词说明
最近在研究Thinking in Java的时候,感觉逆变与协变有点绕,特意整理一下,方便后人.我参考于Java中的逆变与协变,但是该作者整理的稍微有点过于概念化,我在这里简单的说一下 我对于协变于逆 ...
- Java 逆变与协变
最近一直忙于学习模电.数电,搞得头晕脑胀,难得今天晚上挤出一些时间来分析一下Java中的逆变.协变.Java早于C#引入逆变.协变,两者在与C#稍有不同,Java中的逆变.协变引入早于C#,故在形式没 ...
- Java中的逆变与协变 很直接不饶弯的讲出来了
```java 协变 extends只能new 辈分比自己低的家伙 List<? extends Number> list001 = new ArrayList<Integer> ...
- Java泛型的协变与逆变
泛型擦除 Java的泛型本质上不是真正的泛型,而是利用了类型擦除(type erasure),比如下面的代码就会出现错误: 报的错误是:both methods have same erasure ...
- Java协变、逆变、类型擦除
协变.逆变 定义 Java中String类型是继承自Object的,姑且记做String ≦ Object,表示String是Object的子类型,String的对象可以赋给Object的对象.而Ob ...
- Scala中的协变,逆变,上界,下界等
Scala中的协变,逆变,上界,下界等 目录 [−] Java中的协变和逆变 Scala的协变 Scala的逆变 下界lower bounds 上界upper bounds 综合协变,逆变,上界,下界 ...
- 协变(covariance),逆变(contravariance)与不变(invariance)
协变,逆变与不变 能在使用父类型的场景中改用子类型的被称为协变. 能在使用子类型的场景中改用父类型的被称为逆变. 不能做到以上两点的被称为不变. 以上的场景通常包括数组,继承和泛型. 协变逆变与泛型( ...
- C#中的协变OUT和逆变
泛型接口和泛型委托中经常使用可变性 in 逆变,out 协变 从 list<string>转到list<object> 称为协变 (string 从object 派生,那么 ...
- C# 逆变与协变
该文章中使用了较多的 委托delegate和Lambda表达式,如果你并不熟悉这些,请查看我的文章<委托与匿名委托>.<匿名委托与Lambda表达式>以便帮你建立完整的知识体系 ...
随机推荐
- java ---- 认识类和对象
---- 开发方法 结构化开发方法特点: 1.面向功能划分软件结构 2.自顶而下 3.最小的子系统是方法 4.制约了软件的可维护性和扩展性 面向对象开发方法特点: 1.把软件系统看成各种对象和集合 ...
- SQL Server DBCC命令大全
原文出处:https://www.cnblogs.com/lyhabc/archive/2013/01/19/2867174.html DBCC DROPCLEANBUFFERS:从缓冲池中删除所有缓 ...
- Java开发笔记(一百四十五)FXML布局的伸展适配
前面介绍了FXML的基本格式及其控制器的用法,算是打通了FXML方式的编码流程.程序界面通常保持固定尺寸,不过有时也允许用户拖曳窗口大小,不拖不打紧,一拖就可能坏事.像之前的登录窗口,没拖的时候界面如 ...
- laravels 使用laravel-wechat 组件
一. laravels (5.4)使用 laravel-wechat (4.13),出现无法登陆的情况,显示没有code 错误,解决办法 前提:已经在laravels.php 的 cleaners 中 ...
- (一)使用phantomjs将动态HTML页面生成图片
因为工作需要,笔者需要将一个动态的HTML5页面生成图片,并将图片发送给用户. 其中难点在于怎样将动态H5生成图片 笔者翻阅资料后,决定使用phantomjs这个插件,关于这个插件的安装,非常简单,笔 ...
- 『Andrew and Chemistry 树同构』
Andrew and Chemistry Description During the chemistry lesson Andrew learned that the saturated hydro ...
- U9-ERP BuildupDesigner 操作
它的数据库文件配制 D:\UFIDA\UBFV50\U9.VOB.Product.UBF\UBFStudio\Runtime\environment.xml
- IIS 图片 JS CSS 500错误
1.检查站点MIME类型是否可以正常加载
- 【转载】socket通信-C#实现tcp收发字符串文本数据
在日常碰到的项目中,有些场景需要发送文本数据,也就是字符串,比如简单的聊天文字,JSON字符串等场景.那么如何如何使用SharpSocket来收发此类数据呢?其中要掌握的关键点是什么呢? 点击查看原博 ...
- Wireshark教程之二:Wireshark捕获数据分析
使用 Wireshark 选择需要抓包的网络方式,并设置过滤器条件,当有数据通信后即可抓到对应的数据包,这里将分析其每一帧数据包的结构. 以HTTP协议为例,一帧数据包一般包括以下几个部分: Fram ...