Rhyme/Java getClass()与instanceof的区别以及如何编写一个完美的equals()

本文详细介绍了Java中equals()方法的实现原则及其与hashCode()的关系,对比了getClass()与instanceof的区别,并提供了编写equals()和hashCode()的实用指南。
摘要由CSDN通过智能技术生成

Java getClass()与instanceof的区别以及如何编写一个完美的equals()和hashCode()方法

1、首先我们来看下Java规范中的equals()要求有哪些特性

  1. 自反性

    对于任何非空引用有 x.equals(x)=true

  2. 对称性

    y.equals(x)=true;x.equals(y)=true

  3. 传递性

    x.equals(y)=truy ; y.equals(z)=true;则x.equals(z)=true

  4. 一致性

    如果x,y的引用没有发生变化,则反复调用x.equals()方法应该得到相同的结果

  5. 对于任何非空引用x,有x.equals(null)的结果为false

2、getClass()与instanceof在equals()方法中的区别

方法解释
getClass()返回当前对象的类的类型
instanceof用于判断某个对象是否属于属于这个类或者其父类

首先我们来看下面一个超级简单的测试代码

这里写图片描述

测试结果

这里写图片描述

从以上的结果我们可以看出什么呢?

注意,其中最大的一个区别就是 child instanceof Father = truefather instanceof Child = false,并且只有child.getClass()=child.getClass();father.getClass()=father.getClass()

3、编写equals()的完美方法

知道了第二步中的结果,先别急,让我们看看编写equals的正确方法先

首先我们有x.equals(otherObject)

1、检测this与otherObject是不是同一个对象

if(this==otherObject)return true

2、 检测otherObject是不是null

if(otherObject==null)return false

3、比较this与otherObject是否属于同一个类,如果equals()方法在子类中被重写且与父类的equals()方法不同,则使用

if(getClass()!=otherObject.getClass)return false

否则使用(ClassName代表当前类的类名)

if(!(otherObject instanceof ClassName))return false

4、将otherObject转化为这个类的类型

otherObject=(ClassName)otherObject

5、对对象中的属性值进行比较

return Objects.equals(field,otherObject.field)&&Objects.equals(field2,otherObject.field2)...

4、简单分析

好,以上equals()的方法讲完了,我相信你现在肯定有着很多疑惑,没事让我简单的和你说一下这个道理。其实equals的比较方法和我们现实生活中的道理是一样的,比如说我们要比较两个铅笔盒。首先我们判断这两个铅笔盒是不是同一个铅笔盒,如果是那就直接相等。然后我们在判断第二个铅笔盒存在吗?如果不存在,那就是说比较的对象都没有,那肯定返回false;然后我们要判断这两个铅笔盒外表是不是长得一样呀,也就是说他们是不是同一类型,当然我们这里还需要考虑子类和父类的情况,好,如果这两个铅笔盒外表一样,那么接下来我们就要看这两个铅笔盒中的铅笔是不是都一样呀;
这样我们就完成了一个简单的equals()方法;

那么最令人疑惑的地方是哪里呢?本人当初最疑惑的点是第三步中getClass()与instanceof的选择,让我困惑了好长一段时间,这也是我为什么写这篇博客的真正原因。

5、getClass()与instanceof分析解释

我们再来仔细回顾一下,在第三步方法中的描述,如果子类中的equals方法和父类中的equals()方法的的比较规则不一样,这个时候就要使用getClass()了。那好在解释这句话之前我们先来看一段代码

这里写图片描述

这里写图片描述

代码很简单,我们可以看到有一个父类Car它有一个属性run,子类SuperCar有一个额外的属性superPower;好,现在我们来看他们的equals()方法

这里写图片描述
这里写图片描述

我们看到父类是完全按照以上给出的方法完成的,值得注意的是它用的是getClass();

好,现在我们来判断一下我们在子类对象中调用equals(f父类对象)方法会发生什么,首先他会调用父类的equal(),由于父类的equals()方法中此时持有的是子类的this隐式参数,也就是说此时父类中的这行代码getClass()得到的结果是子类的类型,而方法参数中的类型是Car类型,那显然他们不相等。

有点累了,在这里我把心法传给你吧!

子类重新定义了equals()方法往往意味着这个子类中有父类没有的东西,也就是说光是父类的比较方法已经满足不了我了,这个时候我们采取的策略是子类只能和子类比较,子类和父类比较统统是false,这也正是getClass()的作用,其实也很好理解,子类拥有比父类更多的东西,你父类都没有,那我们还比什么,所以这里你应该懂了什么时候用getClass()什么时候用instanceof了。再插一句,那么当我们子类没有比父类更多的东西时,那么我子类当然理所应当能和你父类正常比较啦

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值