简而言之,如果A IS-A B,那么A[] IS-A B[]。
举例:现在有类型Person、Employee和Student。Employee
是一个(IS-A) Person,Student是一个(IS-A)Person。那么下面的语句可以通过编译:

但是上面的代码在运行时却会出错。因为arr[0]实际上是引用一个Employee,可是Student IS-NOT-A
Employee。这样就产生了混乱。这种错误正是由于Java数组的协变性而产生的。那么Java为什么不禁止数组协变呢?因为SE5之前还没有泛型,但很多代码迫切需要泛型来解决问题。

例如Arrays.equals()方法的底层实现调用的是Object.equals()方法,和数组中元素的具体类型无关,这充分利用了Java中任何类型都继承自Object类的特性,避免了为每个类型都重新定义Arrays.equals()方法。而在没有泛型的时代,要让Object[]能接受所有数组类型,最简单的办法就是让数组接受协变,把String[],Integer[]都定义成Object[]的派生类,如何自学英语然后多态就起作用了。

这是基于数组的一个独有特性:

数组记得它内部元素的具体类型,并且会在运行时做类型检查。

因为arr[0]记得它内部的元素类型是Employee,所以运行时给它插入一个Student类型会报错。

这个特性使得Java数组协变带来的影响不会酿成大错——错误最终还是会被检测出来,只不过是从编译时推迟到了运行时。

正是有这个特性,Java当初才敢于把数组设计成协变的。虽然向上转型以后,编译期类型检查放松了,但因为数组运行时对内部元素类型的严格检查,不匹配的类型还是插不进去的。这也是为什么容器Collection不能设计成协变的原因——Collection不做运行时类型检查。

Java容器因为不具有协变性,因而少了灵活性。因此,在Java5中,Java通过通配符和泛型对容器进行了弥补。

关于Java协变性的思考的更多相关文章

  1. Java 8 CompletableFuture思考

    Java 8 CompletableFuture思考 最近一直在用响应式编程写Java代码,用的框架大概上有WebFlux(Spring).R2dbc.Akka...一些响应式的框架. 全都是Java ...

  2. 关于Java 项目的思考总结

    Java 项目思考总结 前言 今天是2017年3月25日,笔者已经毕业半年,工作经验一年. 正好有心思写这个总结. 持续开发 对于Java项目,我所接触的一般就是JavaWeb项目和 Java Jar ...

  3. Java框架的思考

    目前的JAVA 企业级开发框架,我们常用的大致包括IOC AOP MVC ORM框架 1. IOC spring是一个非常棒的ico容器,其思想非常简单,用一个集合对象如MAP 来缓存对象(对象都是单 ...

  4. 关于java对象的思考

    不可变对象和类 由不可变类创建的对象就是不可变对象,要使一个类成为不可变的,它必须满足下面的需求: 所有数据域都是私有的 没有修改器方法 没有一个访问器的方法,它会返回一个指向可变数据域的引用 看下面 ...

  5. 对 Kotlin 与 Java 编程语言的思考

    从长远来看,排名前10的也基本上是Java.C.C++.Python.C#.VB.PHP.JavaScript.至于Kotlin的排名,11月份在编程语言仅排41名,Ratings仅有0.216%. ...

  6. 有 a - b < c 对Java安全性的思考

    软件工程中,不论使用哪种开发语言,安全性一直是一个非常棘手却又重要的问题.安全性是软件开发领域永远的主题之一,而且随着互联网的蜂拥发展而带动的新技术的兴起与革命(比如近几年火起来的node.js,py ...

  7. 关于java异常处理的思考

    学习java的过程中,初学者更多的是为了实验而写代码,而不考虑实际情况中的人机交互过程中的一些问题. 在java项目中,更多的用户不会因为你给了某些限制提醒,他就一定会按照你所给的提示来输入或者操作, ...

  8. JAVA设计方法思考之如何实现一个方法执行完毕后自动执行下一个方法

    今天编程时,突然想起来在一些异步操作或Android原生库的时候,需要我们实现一些方法, 这些方法只需要我们具体实现,然后他们会在适当的时候,自动被调用! 例如AsyncTask,执行玩doInBac ...

  9. java权限设计思考

    1.粗粒度权限设计与细粒度权限设计             粗粒度(Coarse-graind)        表示类别级,即仅考虑对象的类别(the   type   of   object),不考 ...

随机推荐

  1. Java - PhantomJS + EChartsConvert实现ECharts图片保存到服务端

    1.所需工具 1>phantomjs:官网下载http://phantomjs.org/download.html 国内镜像http://npm.taobao.org/dist/phantomj ...

  2. Python入门之format()方法

    在此列出format()方法的一些基本使用: >>> '{}{}{}'.format('圆周率是',3.1415926,'...') '圆周率是3.1415926...' >& ...

  3. 洛谷 P1484 种树(优先队列,贪心,链表)

    传送门 解题思路 第一眼的贪心策略:每次都选最大的. 但是——不正确! 因为选了第i个树,第i-1和i-1棵树就不能选了.所以,要有一个反悔操作. 选了第i个后,我们就把a[i]的值更新为a[l[i] ...

  4. 【JZOJ 3910】Idiot 的间谍网络

    题面: Description 作为一名高级特工,Idiot 苦心经营多年,终于在敌国建立起一张共有n 名特工的庞大间谍网络. 当然,出于保密性的要求,间谍网络中的每名特工最多只会有一名直接领导.现在 ...

  5. [LeetCode] 39. 组合总和

    题目链接 : https://leetcode-cn.com/problems/combination-sum/ 题目描述: 给定一个无重复元素的数组 candidates 和一个目标数 target ...

  6. 初学Git——命令总结

    首先,感谢廖雪峰老师制作的Git教程:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b0 ...

  7. Comet OJ - Contest #0 A题 解方程 (数学)

    题目描述 小象同学在初等教育时期遇到了一个复杂的数学题,题目是这样的: 给定自然数 nn,确定关于 x, y, zx,y,z 的不定方程 \displaystyle \sqrt{x - \sqrt{n ...

  8. C#基础知识之父子类,实例、静态成员变量,构造函数的执行顺序(经典示例)

    父子类.示例.静态成员变量.构造函数的概念的基础理解完全可以利用下面的示例诠释,非常经典,直接上代码: public class ShowInfo { public ShowInfo(string i ...

  9. 3--面试总结-es6

    es6文档:http://es6.ruanyifeng.com/1.es6新特性 let/const 变量的解构赋值(数组的解构赋值,对象的解构赋值,字符串的解构赋值,数值和布尔值的解构赋值,函数参数 ...

  10. SQL查询优化的步骤

    一.定位慢查询 SQL优化的一般步骤:先查询mysql数据库运行状况,然后定位慢查询,再分析sql的执行过程,然后进行优化 1.使用show status查询数据库的运行状况 //显示数据库运行状态 ...