关于Java协变性的思考
简而言之,如果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协变性的思考的更多相关文章
- Java 8 CompletableFuture思考
Java 8 CompletableFuture思考 最近一直在用响应式编程写Java代码,用的框架大概上有WebFlux(Spring).R2dbc.Akka...一些响应式的框架. 全都是Java ...
- 关于Java 项目的思考总结
Java 项目思考总结 前言 今天是2017年3月25日,笔者已经毕业半年,工作经验一年. 正好有心思写这个总结. 持续开发 对于Java项目,我所接触的一般就是JavaWeb项目和 Java Jar ...
- Java框架的思考
目前的JAVA 企业级开发框架,我们常用的大致包括IOC AOP MVC ORM框架 1. IOC spring是一个非常棒的ico容器,其思想非常简单,用一个集合对象如MAP 来缓存对象(对象都是单 ...
- 关于java对象的思考
不可变对象和类 由不可变类创建的对象就是不可变对象,要使一个类成为不可变的,它必须满足下面的需求: 所有数据域都是私有的 没有修改器方法 没有一个访问器的方法,它会返回一个指向可变数据域的引用 看下面 ...
- 对 Kotlin 与 Java 编程语言的思考
从长远来看,排名前10的也基本上是Java.C.C++.Python.C#.VB.PHP.JavaScript.至于Kotlin的排名,11月份在编程语言仅排41名,Ratings仅有0.216%. ...
- 有 a - b < c 对Java安全性的思考
软件工程中,不论使用哪种开发语言,安全性一直是一个非常棘手却又重要的问题.安全性是软件开发领域永远的主题之一,而且随着互联网的蜂拥发展而带动的新技术的兴起与革命(比如近几年火起来的node.js,py ...
- 关于java异常处理的思考
学习java的过程中,初学者更多的是为了实验而写代码,而不考虑实际情况中的人机交互过程中的一些问题. 在java项目中,更多的用户不会因为你给了某些限制提醒,他就一定会按照你所给的提示来输入或者操作, ...
- JAVA设计方法思考之如何实现一个方法执行完毕后自动执行下一个方法
今天编程时,突然想起来在一些异步操作或Android原生库的时候,需要我们实现一些方法, 这些方法只需要我们具体实现,然后他们会在适当的时候,自动被调用! 例如AsyncTask,执行玩doInBac ...
- java权限设计思考
1.粗粒度权限设计与细粒度权限设计 粗粒度(Coarse-graind) 表示类别级,即仅考虑对象的类别(the type of object),不考 ...
随机推荐
- Sequential game
Sequential game Problem Description Sequential detector is a very important device in Hardware exper ...
- Luogu P4562 [JXOI2018]游戏
题目 我们用埃氏筛从\(l,r\)筛一遍,每次把没有被筛掉的数的倍数筛掉. 易知最后剩下来的数(这个集合记为\(S\))的个数就是我们需要选的数,设有\(s\)个,令\(n=r-l+1\). 记\(f ...
- [LeetCode] 45. 跳跃游戏 II
题目链接 : https://leetcode-cn.com/problems/jump-game-ii/ 题目描述: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位 ...
- HNUSTOJ-1690 千纸鹤
1690: 千纸鹤 时间限制: 1 Sec 内存限制: 128 MB提交: 992 解决: 296[提交][状态][讨论版] 题目描述 圣诞节快到了,校园里到处弥漫着粉红色的气息.又是一个情侣秀 ...
- wordpress开发的一些积累
wordpress 攒知识点 记录开发 wordpress 的一些技能点,以备不时之需 短代码 Shortcode 虽然很多插件都是提供,直接在代码中插入类似[Shortcode] 便可以生效,但是很 ...
- 攻防世界--when_did_you_born5
测试文件:https://adworld.xctf.org.cn/media/task/attachments/24937e95ca4744818feebe82ab96902d 1.准备 root@l ...
- Android数据库使用指南(下)
前言 上面已经说了,对表进行修改,其实就是对数据库进行升级,删除表也算升级啊,反正就是发生变化,数据库就需要升级. 所以老实说其实有个地方决定了数据库的版本 public class DBHelper ...
- 42. Trapping Rain Water (JAVA)
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- 解密Qt安装目录的结构
http://c.biancheng.net/view/3866.html 了解 Qt 安装目录的结构虽然不是编程必须的,但是它能练就我们的内功,让我们对 Qt 的编程环境了如指掌.Windows 和 ...
- 020-VMware虚拟机作为OpenStack计算节点,上面的虚拟机无法启动问题解决
问题描述: VMware虚拟机作为OpenStack计算节点,如果安装的操作系统是CentOS7.3,则在此计算节点放置的虚拟机无法正常启动,报如下错误: 在创建计算节点时,为了能让 KVM 能创 ...