1. 定义

逆变和协变描述的经过类型变换后的类型之间的关系。假如AB表示类型,f表示类型变换,A ≤B表示A是B的子类型,那么

  • 如果A ≤Bf(A) ≤f(B),那么f是协变
  • 如果A ≤Bf(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)的更多相关文章

  1. Java 逆变与协变的名词说明

    最近在研究Thinking in Java的时候,感觉逆变与协变有点绕,特意整理一下,方便后人.我参考于Java中的逆变与协变,但是该作者整理的稍微有点过于概念化,我在这里简单的说一下 我对于协变于逆 ...

  2. Java 逆变与协变

    最近一直忙于学习模电.数电,搞得头晕脑胀,难得今天晚上挤出一些时间来分析一下Java中的逆变.协变.Java早于C#引入逆变.协变,两者在与C#稍有不同,Java中的逆变.协变引入早于C#,故在形式没 ...

  3. Java中的逆变与协变 很直接不饶弯的讲出来了

    ```java 协变 extends只能new 辈分比自己低的家伙 List<? extends Number> list001 = new ArrayList<Integer> ...

  4. Java泛型的协变与逆变

    泛型擦除 Java的泛型本质上不是真正的泛型,而是利用了类型擦除(type erasure),比如下面的代码就会出现错误: 报的错误是:both methods  have same erasure ...

  5. Java协变、逆变、类型擦除

    协变.逆变 定义 Java中String类型是继承自Object的,姑且记做String ≦ Object,表示String是Object的子类型,String的对象可以赋给Object的对象.而Ob ...

  6. Scala中的协变,逆变,上界,下界等

    Scala中的协变,逆变,上界,下界等 目录 [−] Java中的协变和逆变 Scala的协变 Scala的逆变 下界lower bounds 上界upper bounds 综合协变,逆变,上界,下界 ...

  7. 协变(covariance),逆变(contravariance)与不变(invariance)

    协变,逆变与不变 能在使用父类型的场景中改用子类型的被称为协变. 能在使用子类型的场景中改用父类型的被称为逆变. 不能做到以上两点的被称为不变. 以上的场景通常包括数组,继承和泛型. 协变逆变与泛型( ...

  8. C#中的协变OUT和逆变

    泛型接口和泛型委托中经常使用可变性 in  逆变,out  协变 从 list<string>转到list<object> 称为协变 (string 从object 派生,那么 ...

  9. C# 逆变与协变

    该文章中使用了较多的 委托delegate和Lambda表达式,如果你并不熟悉这些,请查看我的文章<委托与匿名委托>.<匿名委托与Lambda表达式>以便帮你建立完整的知识体系 ...

随机推荐

  1. package.json中dependencies 与devDependencies 的区别

    首先,dependencies中安装的依赖是生产环境的依赖,即项目要运行所必须安装的包:devDependencies中安装的的依赖是开放环境的依赖,即在开发项目时需要安装的依赖. 其次,在安装依赖的 ...

  2. Nginx配置REWRITE隐藏index.php

    server { listen 80; server_name localhost; root D:\workspace\PHP\Atromic; location / { index index.p ...

  3. uniapp销毁addEventListener事件

    百度了很多vue的方法,结果都不适用,只好自己想办法,也是无关紧要的东西,不影响运行,但是看着心里都烦,有更好的解决方案欢迎指点上报错信息 这是一个监听滚动的方法,离开了那个页面进入详情页发现这个没有 ...

  4. Linux设置SSH隧道连接

    因为安全考虑,服务器防火墙对某些端口进行了限制,原先通过客户端工具可以连接的端口,现在不能连接了,需要通过设置SSH隧道才可以,记录如下.

  5. AnyProxy代理

    背景:当一个公司测试团队有多个人的时候,只需搭建一个AnyProxy服务,其它小伙伴浏览器上打开AnyProxy页面,手机上设置代理就能抓到http.https请求了.解决了部分人电脑不正经的小伙伴f ...

  6. FileChannel详解

    经过前两篇文章的学习,相信对Channel有了一定的整体性认识.接下来通过学习本篇文章,更进一步认识Channel,学习FileChannel的细节 用途 特点 api 原理 一.用途 传统IO中的F ...

  7. centos下 yum快速安装maven

    wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos ...

  8. 移动开发首页业界资讯移动应用平台技术专题 输入您要搜索的内容 基于Java Socket的自定义协议,实现Android与服务器的长连接(二)

    在阅读本文前需要对socket以及自定义协议有一个基本的了解,可以先查看上一篇文章<基于Java Socket的自定义协议,实现Android与服务器的长连接(一)>学习相关的基础知识点. ...

  9. laravel5.4 orm with 用法

    在laravel orm 中一个with 关联方法,需要在模板中先定义表与表之间的关系 /*一对多的关系 */ public function hasManyTemplate(){ return $t ...

  10. UIPath RPA 自动化脚本 机器人从入门到精通

    本文链接:https://blog.csdn.net/qq_27256783/article/details/93619818 一.UiPath介绍 UiPath 是RPA(Robotic Proce ...