[改善Java代码]在equals中使用getClass进行类型判断
建议47: 在equals中使用getClass进行类型判断
本节我们继续讨论覆写equals的问题。这次我们编写一个员工Employee类继承Person类,这很正常,员工也是人嘛,而且在JEE中JavaBean有继承关系也很常见,代码如下:
1 public class Client { 2 public static void main(String[] args) { 3 Employee e1 = new Employee("张三",100); 4 Employee e2 = new Employee("张三",1001); 5 Person p1 = new Person("张三"); 6 System.out.println(p1.equals(e1)); 7 System.out.println(p1.equals(e2)); 8 System.out.println(e1.equals(e2)); 9 } 10 } 11 12 class Person{ 13 private String name; 14 15 public Person(String _name){ 16 name = _name; 17 } 18 19 @Override 20 public boolean equals(Object obj) { 21 if(obj instanceof Person){ 22 Person p = (Person) obj; 23 return name.equalsIgnoreCase(p.getName().trim()); 24 } 25 return false; 26 } 27 28 public String getName() { 29 return name; 30 } 31 32 public void setName(String name) { 33 this.name = name; 34 } 35 } 36 37 class Employee extends Person{ 38 private int id; 39 /*id的getter/setter方法省略*/ 40 public Employee(String _name,int _id) { 41 super(_name); 42 id = _id; 43 } 44 45 public int getId() { 46 return id; 47 } 48 49 public void setId(int id) { 50 this.id = id; 51 } 52 53 @Override 54 public boolean equals(Object obj) { 55 if(obj instanceof Employee){ 56 Employee e = (Employee) obj; 57 return super.equals(obj)&& e.getId() == id; 58 } 59 return false; 60 } 61 }
输出结果:
true true false
很不给力嘛,p1竟然等于e1,也等于e2,为什么不是同一个类的两个实例竟然也会相等呢?这很简单,因为p1.equals(e1) 是调用父类Person的equals方法进行判断的,它使用instanceof关键字检查e1是否是Person的实例,由于两者存在继承关系,那结果当然是true了,相等也就没有任何问题了,但是反过来就不成立了,e1或e2可不等于p1,这也是违反对称性原则的一个典型案例。
更玄的是p1与e1、e2相等,但e1竟然与e2不相等,似乎一个简单的等号传递都不能实现。这才是我们要分析的真正重点:e1.equals(e2)调用的是子类Employee的equals方法,不仅仅要判断姓名相同,还要判断工号是否相同,两者工号是不同的,不相等也是自然的了。等式不传递是因为违反了equals的传递性原则,传递性原则是指对于实例对象x、y、z来说,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true。
这种情况发生的关键是父类使用了instanceof关键字,它是用来判断是否是一个类的实例对象的,这很容易让子类“钻空子”。想要解决也很简单,使用getClass来代替instanceof进行类型判断,Person类的equals方法修改后如下所示:
1 public boolean equals(Object obj) { 2 if(obj!=null && obj.getClass() == this.getClass()){ 3 Person p = (Person) obj; 4 if(p.getName()==null || name==null){ 5 return false; 6 }else{ 7 return name.equalsIgnoreCase(p.getName()); 8 } 9 } 10 return false; 11 }
当然,考虑到Employee也有可能被继承,也需要把它的instanceof修改为getClass。总之,在覆写equals时建议使用getClass进行类型判断,而不要使用instanceof。
[改善Java代码]在equals中使用getClass进行类型判断相关推荐
- [改善Java代码]减少HashMap中元素的数量
在系统开发中我们经常会使用HashMap作为数据集容器,或者是用缓冲池来处理,一般很稳定,但偶尔也会出现内存溢出的问题(OutOfMemory错误),而且这经常是与HashMap有关的.而且这经常是与 ...
- [改善Java代码]在接口中不要存在实现代码
第3章 类.对象及方法 书读得多而不思考,你会觉得自己知道的很多. 书读得多而思考,你会觉得自己不懂的越来越多. -伏尔泰 在面向对象编程(Object-Oriented Programming,O ...
- java 代码解析工具_改善 Java 代码质量的工具与方法
原标题:改善 Java 代码质量的工具与方法 我们可能见过上面的有关代码质量的图片,究竟如何衡量一段代码好坏? 代码质量是什么?为什么它很重要? 作家通过他的著作来讲述了一个清晰的.令人信服的故事.他 ...
- 教你如何使用Java代码从网页中爬取数据到数据库中——网络爬虫精华篇
文章目录 1:网络爬虫介绍 2:HttpClients类介绍 2.1 HttpGet参数问题 2.2 HttpPost参数问题 2.3 连接池技术问题 3:Jsoup介绍 4:动手实践如何抓取网页上数 ...
- 改善Java代码有哪些方法?
前言 Java是一门优秀的面向对象的编程语言,针对遇到同样的一个问题会有很多中解法哪种实现方法是最好的呢,还需要不断的探究JDK的底层原理.我会例出Java改善的建议哦,希望大家可以在平时开发工作去使 ...
- java代码在jsp中怎么写_在jsp中写java代码
该服务器上的所有的访问者的所有 jsp 页面 D.该服务器上的所有的访问者的所有 jsp 页面和 Java 程序 6.在 JSP 中调用 JavaBean 时不会用到的标记是( )...... jav ...
- Java代码---求数组中的平均值
Java代码-求数组中的平均值 /*** 求数组中的平均值*/ class Demo5 {public static void main(String[] args) {int[] array = { ...
- C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断...
C#保留2位小数几种场景总结 场景1: C#保留2位小数,.ToString("f2")确实可以,但是如果这个数字本来就小数点后面三位比如1.253,那么转化之后就会变成1.25. ...
- [改善Java代码]覆写equals方法必须覆写hashCode方法
覆写equals方法必须覆写hashCode方法,这条规则基本上每个Javaer都知道,这也是JDK API上反复说明的,不过为什么要这样做呢?这两个方法之间有什么关系呢?本建议就来解释该问题,我们先 ...
- [改善Java代码]避开基本类型数组转换列表陷阱
开发中经常用到Arrays和Collections这两个工具类. 在数组和列表之间进行切换.非常方便.但是也会遇到一些问题. 看代码: import java.util.Arrays; import ...
最新文章
- C++ 虚函数与存虚函数
- MacOS无法登录App Store修复
- python数独代码_python 实现计算数独
- 地震射线追踪与有限差分正演模拟小软件
- Ajax Control Toolkit--Slider:有朝一日倒过来
- 230.二叉搜索树中第K小的元素
- android 修复工具下载,安卓数据恢复软件(FonePaw for Android)
- 这么多技术我该怎么学 杨中科
- 微信小程序,电子商城中快速实现收货地址(包含前端和后台实现)
- 基于SSM架构的网上书城系统
- Facebook IPO更改投行佣金标准 比例或降至1%
- Paper之ICASSPIEEEAUDIOSPE:2018~2019年ICASSP国际声学、语音和信号处理会议IEEE-ACM T AUDIO SPE音频、语音和语言处理期刊最佳论文简介及其解读
- ubuntu(服务端)+windows(客户端)搭建iscsi
- dubbo源码分析总结
- “掌商工程”让海派盆景与白领互添绿意
- 汽车多重定位,实时定位追踪,远程查看汽车运行轨迹
- webview的java与js互操作
- Hackintosh相关资源站
- 电脑启动项和系统引导项设置
- 2018年广东工业大学文远知行杯新生程序设计竞赛 1007 活在无尽梦境的后续 β
热门文章
- 安装ECShop报 Non-static method cls_image::gd_version() should not be called statically 解决方案
- GitHub 学习和使用
- HTML(三)选择器--复杂选择器
- CSS-Box模型--理解与整理
- AlwaysOn业务IP和高可用IP分开使用(四)
- ios 图片合成 处理合成模糊 水印 模板图片合成
- pip install 出现报asciii码错误的解决
- 【转】Unix的文件系统的内部结构,主要是超级块、inode相关知识
- rpm软件管理程序,yum仓库的作用
- Learn UML with JUDE(中文版)