equal() 方法在 Java 中不起作用

equal() Method doesn't work in Java

以下代码片段无效。为什么?它们是相同class的对象,并且它们具有相同的实例变量值。有什么问题?

Pen bluePen = new Pen("Faber Castel");
Pen bluePen1 = new Pen("Faber Castel");

if( bluePen.equals(bluePen1) )
    System.out.println("They are equal");

输出为空。当我这样做时:

Pen bluePen = new Pen();
Pen varPen = bluePen;

if( bluePen == varPen)
    System.out.println(“They are identical”);

没有问题。输出为 "They are identical"。

我试图理解 == 和 equal() 方法之间的区别。我在这个网站上读到了这两件事的区别。但由于以下代码片段无法正常工作,我感到困惑:

Pen bluePen = new Pen("Faber Castel");
Pen bluePen1 = new Pen("Faber Castel");

if( bluePen.equals(bluePen1) )
    System.out.println("They are equal");

谁能给我解释一下为什么上面的代码不输出"They are equal"?

从这个问题 (Why do we have to override the equals() method in Java?) 中,您可以了解到 Java 比较两个对象的默认方式是通过它们的内存地址。如果您创建两个实例,那么这两个实例将具有不同的内存地址。因此,它们不相等。 (底线是该方法确实有效,但不是您预期的那样)

这就是为什么您必须重写 Pen class 中的 equals 方法才能 'tell' Java 如果 Pen.Name 等于,对象本身等于。

你如何定义"equal"?

Java 对您的对象一无所知。它可以编译和 运行 代码,但它无法告诉您哪些成员在确定诸如相等性或排序顺序或类似内容时是重要的。这是您需要定义的逻辑。在没有该逻辑的情况下,默认实现是引用相等。

在您的第一个示例中,变量引用两个不同的对象实例。所以他们不平等。在您的第二个示例中,变量引用相同的对象实例。所以他们是平等的。

为了定义相等性,您需要覆盖 class 中的 equals()(和 hashcode())。类似于:

@Override
public int hashCode() {
    // TODO: compute and return a hash code
}

@Override
public boolean equals(Object obj) {
   // TODO: determine and return if the supplied instance is logically equal to the current instance
}

网上有很多good examples如何有效地实现这些方法。不过,实际上逻辑很简单。 hashCode() 应该 return 一个值,该值对于对象的任何 "non-equal" 实例都是唯一的,根据用于确定相等性的字段计算。 equals() 应该确定这些字段的相等性。

当您开始考虑对象在各种业务逻辑域中表示什么时,整体概念在语义上变得非常重要。例如,是什么让两个 Person 对象相等?如果他们的名字相同?显然不是,因为两个人可以有相同的名字。他们的姓名、地址和 phone 号码的组合?没有。 (我的兄弟和我的父亲共享了所有这些属性 20 年。)什么样的属性组合 确保 Persondistinct来自另一个 Person?不同业务领域的答案可能大相径庭。

在Java中,当“==”运算符用于比较2个对象时,它会检查对象是否指向内存中的同一位置。换句话说,它检查 2 个对象名称是否基本上是对同一内存位置的引用。

equals() 方法实际上与“==”运算符的行为相同——这意味着它会检查两个对象是否引用内存中的相同位置。但是,equals 方法实际上是为了比较 2 个对象的内容,而不是它们在内存中的位置。

。当一个对象等于另一个对象时,您甚至可以重写 equals() 方法来定义自己