使用Java的equals方法测试对象是否相等

3

我想问一个关于在Java中使用equals方法测试对象相等性的问题。

我是Java的初学者,目前正在阅读《Java 9合1》Dummies书籍。

我编写了以下代码来检查两个Employee对象的相等性:

public class TestEquality2 {
    public static void main (String [] args) {
        Employee emp1 = new Employee ("Martinez", "Anthony");
        Employee emp2 = new Employee ("Martinez", "Anthony");
        if (emp1.equals(emp2))
            System.out.println("These employees are the same");
        else
            System.out.println("These employees are different.");
    }
}

class Employee {
    private String firstName;
    private String lastName;

    public Employee (String firstName, String lastName) {
        this.lastName = lastName;
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public boolean equals (Object obj) {
        // an object must equal itself
        if (this == obj)
            return true;

        // no object equals null
        if (this == null)
            return false;

        if (this.getClass() != obj.getClass())
            return false;

        // Cast to an employee, then compare the fields
        Employee emp = (Employee) obj;
        // is this the string's equals method?
        return this.lastName.equals(emp.getLastName()) && this.firstName.equals(emp.getFirstName());
    }
}

涉及的代码行是equals(Object obj)方法中的最后一行。

根据代码,我已经重写了默认的 Object equals() 方法并提供了自己的设计,但这里我感到困惑:

return this.lastName.equals(emp.getLastName()) && this.firstName.equals(emp.getFirstName());

我知道lastName 是一个字符串,但我正在使用的equals()方法,是针对Stringequals()方法还是我刚刚定义的方法?如果是后者,我知道会创建一个递归情况,尽管我相信我正在使用String equals(),但为了完整起见,我想澄清一下。


5
附注:if (this == null) 是无意义的。你是否想表达的是 if (obj == null) - ernest_k
2
你正在调用一个字符串类型的字段上的方法。所以是的,这是字符串方法,而不是员工方法。如果A和B之间没有任何关系(例如,如果A和B之间没有继承关系),则不能在类A的对象上调用类B的方法。 - JustAnotherDeveloper
1
是的,您正在使用String.equals方法。 - Sridhar Chidurala
@ernest_k 我考虑过这个问题。书中将其描述为“非空规则”,并给出了代码 if(this==null) return true,但我怀疑它应该是 if(obj==null) return true - 感谢您的澄清!既然您已经确认了,我会进行更新! - bodn19888
1
如果 if(this==null) 为真,那么在方法执行之前必然会导致 NullPointerException。而 if(obj==null) 应该返回 **false**,而不是 true - ernest_k
@ernest_k 当然,非常明白!非常感谢! - bodn19888
2个回答

3

lastName 是一个 String,所以调用 this.lastName.equals(emp.getLastName()) 将使用 Stringequals 方法实现。当然,对于名字的比较也是如此。


0

基本上,你重写equals()方法是因为你想让内存中的两个不同对象在你的应用程序中被视为相等,就像在你的情况下,你创建了如下两个不同的Employee类对象:

Employee emp1 = new Employee ("Martinez", "Anthony");
Employee emp2 = new Employee ("Martinez", "Anthony");

这些对象实际上是内存中的两个不同对象,或者从现实生活的角度来看,它们是两个不同的个体。如果您不覆盖equals()方法,则会检查Object类中的equals()方法,其实现如下:

public boolean equals(Object obj) {
     return (this == obj);
}

emp1.equals(emp2)会返回false。

但是也许你的应用逻辑是希望这两个个体被视为相等(相同),那么在这种情况下,你需要重写equals()方法。

在重写equals时,你可以选择基于什么标准来判断两个个体(员工或对象)是否相等,就像在你的情况下,你选择了firstName和lastName(根据你的需求,你也可以只选择lastName)。

因此,在以下代码中,基本上你是在说如果两个员工的firstName和surName相等,则认为它们相等,即使你知道它们是两个不同的个体(内存中的对象):

return this.lastName.equals(emp.getLastName()) && this.firstName.equals(emp.getFirstName());

而你正在调用字符串类的equals()方法,对lastName和firstName进行比较。Java库开发人员已经重写了String类的equals()方法,如下所示:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String aString = (String)anObject;
            if (coder() == aString.coder()) {
                return isLatin1() ? StringLatin1.equals(value, aString.value)
                                  : StringUTF16.equals(value, aString.value);
            }
        }
        return false;
    }

希望这对你有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接