关于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),不考 ...
随机推荐
- Nginx 的方向代理及配置
最近有打算研读nginx源代码,看到网上介绍nginx可以作为一个反向代理服务器完成负载均衡.所以搜罗了一些关于反向代理服务器的内容,整理综合. 一 概述 反向代理(Reverse Proxy)方式 ...
- Julia出现错误ERROR: LoadError: syntax: try without catch or finally
因项目要求进行机器学习数据可视化,要求尝试使用Julia,在此,记录下遇到的坑,仅为记录效果.后续陆续更新. 问题一:关于LightML库中的坑:ERROR: LoadError: syntax: t ...
- java 数组详细介绍
一.概述 数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理 数组常见概念: 数组名, 下标(或索引), 元素, 数组的长度 数组本 ...
- restful风格详解
一.概念 RESTful架构,就是目前最流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所以正得到越来越多网站的采用. REST这个词,是Roy Thomas Fielding在他 ...
- java 覆盖
作者:又见那斯 java中覆盖基于面向对象三大特征之:继承,同时又和另一特征:多态有重要的联系,本文中讨论的有关java中覆盖的一些知识,其实在写代码的时候或许不会用到,不过知道的话总会有用处.如有错 ...
- Redis持久化存储与主从复制
4. redis持久化 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. 4.1 ...
- Mac 切换bash zsh等shell
现在假设大家都安装了iTerm2,我们先把bash切换成zsh,使用命令行如下: chsh -s /bin/zsh 执行命令后,会让你输入电脑的密码,输入即可.完成后,需要完全退出iTerm2,再次进 ...
- Label显示时间
package 第十一章; import java.awt.Button; import java.awt.Color; import java.awt.Font; import java.awt.F ...
- Restful,SAOP,SOA,RPC的基础理解
什么是Restful restful是一种架构设计风格,提供了设计原则和约束条件,而不是架构.而满足这些约束条件和原则的应用程序或设计就是 RESTful架构或服务. 主要的设计原则: 资源与URI ...
- Python性能分析工具Profile
Python性能分析工具Profile 代码优化的前提是需要了解性能瓶颈在什么地方,程序运行的主要时间是消耗在哪里,对于比较复杂的代码可以借助一些工具来定位,python 内置了丰富的性能分析工具,如 ...