繁体   English   中英

重载或覆盖 equals() 方法

[英]overloading or overriding equals() method

我对以下场景中首先调用的内容有些困惑:

我有一个带有名字和年龄的 Person 类。

public class Person {
  private int age;
  private String name;

  //constructor, getters, ...
}

我现在尝试比较具有相同字段值的两个单独的Person对象,即相同的名称,相同的年龄

System.out.println(person1.equals(person2));

我显然收到了一个false返回值,因为我还没有重载equals(Obj object)方法。

但是说我没有重载它,而是编写另一个仅带有Person参数的equals()方法:

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 有点陌生。

覆盖是当您实现已在超类中声明的方法时。 要符合覆盖条件,覆盖的签名必须与被覆盖的方法的签名匹配(在某些容差范围内)。

重载是指您有多个名称相同但签名不同的方法。

在存在重载的情况下,调用哪一个完全由调用站点上参数静态类型决定。 在您的示例中,您有两个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) - 它看起来像一个覆盖,但实际上它是一个重载,并且不会在您认为它发生时被调用。

实际上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 给出了相应的警告(橙色标记)。


提示:

  • 使用getAgegetName Java中的骆驼案例。 Java 中的约定在任何地方都非常严格。

  • 不要重载equals并使用@Override 在很大程度上取决于原始的equals ,众所周知,IDE 会警告personJoop.equals(dog)它将总是失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM