重载或重写 equals() 方法

Bia*_*ach 2 java oop overriding

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

我有一个包含姓名和年龄的 Person 类。

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

  //constructor, getters, ...
}
Run Code Online (Sandbox Code Playgroud)

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

System.out.println(person1.equals(person2));
Run Code Online (Sandbox Code Playgroud)

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

但是假设我不重写它,而是编写另一个equals()仅带有参数的方法Person

public equals(Person person) {
  return person.get_age()==this.age && person.get_name().equals(this.name);
}
Run Code Online (Sandbox Code Playgroud)

现在调用哪个方法以及为什么?下面的行仍然返回false

System.out.println(person1.equals(person2));
Run Code Online (Sandbox Code Playgroud)

除非我强迫person2被解释为Person. 因此下面的行返回true

System.out.println(person1.equals((Person)person2));
Run Code Online (Sandbox Code Playgroud)

这就是令我困惑的地方,我现在删除了该类型转换,Person并且由于某种原因,当我一次又一次地构建和运行代码时,它不断返回truefalse强制它再次开始返回(即再次继续采用默认方法)的唯一方法equals(Object obj)是删除该equals(Person person)方法,运行代码一次,然后粘贴回我刚刚删除的方法。现在,这种比较又false再次出现了。

JVM 是否缓存了某些中间状态?老实说,我对java有点陌生。

Bri*_*etz 5

重写是指实现已在超类中声明的方法。要符合覆盖的资格,覆盖的签名必须与被覆盖的方法的签名匹配(在一定的容差范围内)。\xe2\x80\x8b

\n

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

\n

在存在重载的情况下,调用哪一个重载仅由调用站点处参数的静态类型决定。在您的示例中,您有两个重载equals

\n
boolean equals(Object o) { ... }\nboolean equals(Person p) { ... }\n
Run Code Online (Sandbox Code Playgroud)\n

你打电话时:

\n
Person p = ...\n... equals(p) ...\n
Run Code Online (Sandbox Code Playgroud)\n

重载选择过程如下:

\n
    \n
  • 确定参数的静态类型。
  • \n
  • 确定哪些重载适用(使用数量、子类型、转换等)
  • \n
  • 如果不止一项适用,请确定最具体的一项。
  • \n
  • 如果两个或多个同样具体,则会发出编译时错误。
  • \n
\n

这里,参数类型是Person,并且两个重载都适用(因为 aPerson是一个Object),但equals(Person)更具体,因此调用了一个。

\n

如果我们稍微改变一下故事:

\n
Object p = new Person(...);\n... equals(p) ...\n
Run Code Online (Sandbox Code Playgroud)\n

现在, 的静态类型pObject,因此只有第一个重载 -- equals(Object)-- 适用。我们所知道的是它是一个Object;它碰巧持有 aPerson是我们静态不知道的事情。(我们可以使用 动态地找出它instanceof。)

\n

总结一下:

\n
    \n
  • 表达式有静态(编译时)和动态(运行时)类型;
  • \n
  • 重载选择纯粹是基于静态类型来完成的。
  • \n
\n

现在,您可能不想声明equals(Person)您在这里看到的相同问题 - 它看起来像一个覆盖,但实际上它是一个重载,并且当您认为它会被调用时不会被调用。

\n