java - 重载或覆盖 equals() 方法
问题描述
在以下情况下,我对首先调用的内容有点困惑:
我有一个带有名字和年龄的 Person 类。
public class Person {
private int age;
private String name;
//constructor, getters, ...
}
我现在尝试比较两个Person
具有相同字段值的单独对象,即相同的名称,相同的年龄
System.out.println(person1.equals(person2));
我显然收到了一个false
返回值,因为我还没有重写该equals(Obj object)
方法。
但是说我不覆盖它,我只用一个参数编写另一个equals()
方法:Person
public equals(Person person) {
return person.get_age()==this.age && person.get_name().equals(this.name);
}
现在调用哪个方法,为什么?下面的行仍然返回false
System.out.println(person1.equals(person2));
除非我强制person2
解释为Person
. 因此下面的行返回true
System.out.println(person1.equals((Person)person2));
这就是让我感到困惑的地方,我现在删除了该类型转换,Person
并且由于某种原因,当我一次又一次地构建和运行代码时,它不断返回true
。强制它再次开始返回的唯一方法false
,即再次继续采用默认equals(Object obj)
方法是删除该equals(Person person)
方法,运行一次代码,然后将我刚刚删除的方法粘贴回去。现在比较false
再次返回。
JVM是否缓存了一些中间状态?老实说,我对java有点陌生。
解决方案
覆盖是当您实现已在超类中声明的方法时。要成为覆盖,覆盖的签名必须与被覆盖的方法的签名匹配(在一定的容差范围内)。</p>
重载是指您有多个名称相同但签名不同的方法。
在存在重载的情况下,调用哪个重载仅由调用站点上参数的静态类型决定。在您的示例中,您有两个重载equals
:
boolean equals(Object o) { ... }
boolean equals(Person p) { ... }
你打电话时:
Person p = ...
... equals(p) ...
过载选择过程如下:
- 确定参数的静态类型。
- 确定哪些重载适用(使用arity、子类型、转换等)
- 如果有多个适用,请确定最具体的一个。
- 如果两个或更多相同,则会发出编译时错误。
在这里,参数类型是Person
,并且两个重载都适用(因为 aPerson
是 an Object
),但equals(Person)
更具体,因此调用了一个。
如果我们稍微改变一下故事:
Object p = new Person(...);
... equals(p) ...
p
现在, is的静态类型Object
,所以只有第一个重载 -- equals(Object)
-- 适用。我们只知道它是一个Object
; 它碰巧持有 aPerson
是我们静态不知道的。(我们可以用 动态找出它instanceof
。)
总结一下:
- 表达式既有静态(编译时)类型,也有动态(运行时)类型;
- 重载选择完全基于静态类型。
现在,您可能不想equals(Person)
为您在此处看到的相同问题声明 - 它看起来像一个覆盖,但实际上它是一个重载,并且不会在您认为它这样做时被调用。
推荐阅读
- c# - 用我应该替换 dirX 让我的子弹左右射击
- r - 查找三元组概率的 data.table 错误和警告
- r - 数据帧返回到 spatialPolygonsDataFrame
- python - AWS IoT 策略未插入策略变量 (iot:ClientId)
- node.js - 如何在MVC的同一个项目中使用(登录/注册)和(数据库CRUD)的功能?
- python-3.x - google.oauth2.credentials.Credentials 使用有效令牌失败
- reactjs - 我的 bundle.js 很大(1.88MiB),我似乎无法减少它
- css - Mui LinearProgress Bar 停止在 display flex 上显示
- nginx - nginx问题背后的Artifactory 7.x
- r - 与 R 中交替第二分量的相关性