重载或覆盖 equals() 方法
overloading or overriding equals() method
对于在以下情况下首先调用什么,我有点困惑:
我有一个人 class 有名字和年龄。
public class Person {
private int age;
private String name;
//constructor, getters, ...
}
我现在尝试比较具有相同字段值的两个单独的 Person
对象,即相同的名称、相同的年龄
System.out.println(person1.equals(person2));
我显然收到了一个 false
return 值,因为我还没有覆盖 equals(Obj object)
方法。
但是说我没有重写它,而是编写了另一个 equals()
方法,仅使用 Person
参数:
public equals(Person person) {
return person.get_age()==this.age && person.get_name().equals(this.name);
}
现在调用哪个方法,为什么?下面一行还是returns false
System.out.println(person1.equals(person2));
除非我强制将 person2
解释为 Person
。因此下面的行 returns true
System.out.println(person1.equals((Person)person2));
让我感到困惑的是,我现在删除了转换为 Person
的类型,出于某种原因,当我一次又一次地构建和 运行 代码时,它会不断返回 true
.强制它再次启动 returning false
的唯一方法,即再次继续采用默认的 equals(Object obj)
方法是删除 equals(Person person)
方法,运行宁代码一次,然后粘贴回我刚刚删除的方法。现在比较再次 returning false
。
JVM 是否缓存了一些中间状态?老实说,我对 java 有点陌生。
其实Person
有两个方法:
boolean equals(Person);
boolean equals(Object);
(来自对象)
所以显然 person2
没有被识别为 Person
。
可能的解释是忘记了(丢弃)泛型类型。
Person person = new Person();
List<Person> list = new ArrayList(); // Should have been new ArrayList<>();
...
if (person.equals(list.get(0)) { // equals(Object)
使用前泛型类型,编译器不再检查并返回到对象列表。也许您的 IDE 给出了相应的警告(橙色标记)。
提示:
使用getAge
和getName
; Java 中的驼峰式大小写。 java 中的约定在任何地方都非常严格。
不要重载 equals
并使用 @Override
。很大程度上取决于原始的 equals
,并且已知 IDE 会在 personJoop.equals(dog)
上警告它总是会失败。
Overriding 是当您实现已在超类中声明的方法时。要符合覆盖条件,覆盖的签名必须匹配(在一定容差范围内)被覆盖的方法的签名。
重载 是指您有多个同名但签名不同的方法。
在存在重载的情况下,调用哪个重载仅由调用站点 的参数的静态类型决定。在您的示例中,您有两个重载 equals
:
boolean equals(Object o) { ... }
boolean equals(Person p) { ... }
当你打电话时:
Person p = ...
... equals(p) ...
过载选择过程如下:
- 确定参数的静态类型。
- 确定哪些重载适用(使用元数、子类型、转换等)
- 如果有多个适用,请确定最具体的一个。
- 如果两个或多个相同,则会发出编译时错误。
这里,参数类型是Person
,两种重载都适用(因为Person
是Object
),但是equals(Person)
更具体,所以那个叫。
如果我们稍微改变一下故事:
Object p = new Person(...);
... equals(p) ...
现在,p
的静态类型是 Object
,因此只有第一个重载 - equals(Object)
- 适用。我们所知道的是它是一个 Object
;它恰好持有 Person
是我们静态不知道的东西。 (我们可以用 instanceof
动态地找到它。)
总结一下:
- 表达式有静态(编译时)和动态(运行时)类型;
- 重载选择完全基于静态类型。
现在,您可能不想为您在此处看到的相同问题声明 equals(Person)
-- 它看起来像是重写,但实际上是重载,并且不会在以下情况下被调用你认为是的。
对于在以下情况下首先调用什么,我有点困惑:
我有一个人 class 有名字和年龄。
public class Person {
private int age;
private String name;
//constructor, getters, ...
}
我现在尝试比较具有相同字段值的两个单独的 Person
对象,即相同的名称、相同的年龄
System.out.println(person1.equals(person2));
我显然收到了一个 false
return 值,因为我还没有覆盖 equals(Obj object)
方法。
但是说我没有重写它,而是编写了另一个 equals()
方法,仅使用 Person
参数:
public equals(Person person) {
return person.get_age()==this.age && person.get_name().equals(this.name);
}
现在调用哪个方法,为什么?下面一行还是returns false
System.out.println(person1.equals(person2));
除非我强制将 person2
解释为 Person
。因此下面的行 returns true
System.out.println(person1.equals((Person)person2));
让我感到困惑的是,我现在删除了转换为 Person
的类型,出于某种原因,当我一次又一次地构建和 运行 代码时,它会不断返回 true
.强制它再次启动 returning false
的唯一方法,即再次继续采用默认的 equals(Object obj)
方法是删除 equals(Person person)
方法,运行宁代码一次,然后粘贴回我刚刚删除的方法。现在比较再次 returning false
。
JVM 是否缓存了一些中间状态?老实说,我对 java 有点陌生。
其实Person
有两个方法:
boolean equals(Person);
boolean equals(Object);
(来自对象)
所以显然 person2
没有被识别为 Person
。
可能的解释是忘记了(丢弃)泛型类型。
Person person = new Person();
List<Person> list = new ArrayList(); // Should have been new ArrayList<>();
...
if (person.equals(list.get(0)) { // equals(Object)
使用前泛型类型,编译器不再检查并返回到对象列表。也许您的 IDE 给出了相应的警告(橙色标记)。
提示:
使用
getAge
和getName
; Java 中的驼峰式大小写。 java 中的约定在任何地方都非常严格。不要重载
equals
并使用@Override
。很大程度上取决于原始的equals
,并且已知 IDE 会在personJoop.equals(dog)
上警告它总是会失败。
Overriding 是当您实现已在超类中声明的方法时。要符合覆盖条件,覆盖的签名必须匹配(在一定容差范围内)被覆盖的方法的签名。
重载 是指您有多个同名但签名不同的方法。
在存在重载的情况下,调用哪个重载仅由调用站点 的参数的静态类型决定。在您的示例中,您有两个重载 equals
:
boolean equals(Object o) { ... }
boolean equals(Person p) { ... }
当你打电话时:
Person p = ...
... equals(p) ...
过载选择过程如下:
- 确定参数的静态类型。
- 确定哪些重载适用(使用元数、子类型、转换等)
- 如果有多个适用,请确定最具体的一个。
- 如果两个或多个相同,则会发出编译时错误。
这里,参数类型是Person
,两种重载都适用(因为Person
是Object
),但是equals(Person)
更具体,所以那个叫。
如果我们稍微改变一下故事:
Object p = new Person(...);
... equals(p) ...
现在,p
的静态类型是 Object
,因此只有第一个重载 - equals(Object)
- 适用。我们所知道的是它是一个 Object
;它恰好持有 Person
是我们静态不知道的东西。 (我们可以用 instanceof
动态地找到它。)
总结一下:
- 表达式有静态(编译时)和动态(运行时)类型;
- 重载选择完全基于静态类型。
现在,您可能不想为您在此处看到的相同问题声明 equals(Person)
-- 它看起来像是重写,但实际上是重载,并且不会在以下情况下被调用你认为是的。