看不懂这个equals方法的实现

Dont understand this implementaion of equals method

几天前,我的教授向我们展示了如何实现 equals 方法等等。

这是他的 equals 方法的代码示例,我有一部分不明白:

public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Knjiga other = (Knjiga) obj;
    return Objects.equals(isbn,other.isbn);
}

在第一个 if 语句中,他检查 this(当前对象)是否与对象 obj 具有相同的引用(这就是 == 运算符的作用?只比较两个引用)

如果他们得到相同的引用,它会 return 正确吗? 但是我们永远不会检查其他字段,例如 isbn 以及我们可以放置的更多字段,因为如果这两个对象具有相同的引用,方法将永远不会到达该部分。

在我看来,此方法类似于双等号运算符,因为这两个都不会检查字段,仅参考 ?

如果被比较的两个对象具有相同的引用,则这是同一个对象,比较其他任何对象都没有意义。您可以立即 return true 并保存一些比较。

在这种情况下,保证其他属性相等。

如果(this == obj)为真,则为同一个对象,显然是相等的。

如果这两个 if 子句不成立

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

这意味着这两个对象都来自同一个class但不是同一个对象所以然后用

Knjiga other = (Knjiga) obj;
return Objects.equals(isbn,other.isbn);

检查两个对象的 isbn 是否相等,如果相等则两个 Knjiga 对象也相同。

考虑以下代码:

    String s1 = new String("Test");
    String s2 = new String("Test");
    String s3 = s2;
    String s4 = "Test";
    String s5 = "Test";
    System.out.println(s1 == s2); //Prints false
    System.out.println(s2 == s3); //Prints true
    System.out.println(s3 == s4); //Prints false
    System.out.println(s4 == s5); //Prints true

s1s2 是 String 对象的新实例。仅仅因为它们具有相同的表观价值"Test",它们对你的程序来说不一定具有相同的价值。因此,这两者在对象上并不相等。

s3s2 的精确副本,这意味着它是 s2 的 String 实例的精确副本。这反过来意味着它们在实例方面是客观平等的。

s4是直接赋值给"Test"的String,不一定是String对象的新实例。因此,客观上,他们并不平等。 (参见 String Interning

s5也直接赋值给"Test",因此相当于s4。同样,请参阅字符串实习以了解有关其工作原理的详细信息。

这是描述您的情况的一种不太复杂的方式,但应该对对象比较的基础知识给出一个很好的解释。

您代码的 equals 方法的逻辑:

  1. First condition: 很明显。如果两个对象的引用相同,return true

    if (this == obj)
        return true;
    
  2. Second condition: 如果其他对象为 NULL,return false

    if (obj == null)
       return false;
    
  3. Third condition:现在当前对象和其他对象都不为空。检查两个对象的 className 是否相同。如果 class 不同,则 return 为假。

     if (getClass() != obj.getClass())
        return false;
    
  4. Fourth condition: 现在两个对象都不为空并且属于同一个 class。检查这些对象的属性 [isbn in this example] 是否相同。如果它们不相同,则 return 错误。

     Knjiga other = (Knjiga) obj;
     return Objects.equals(isbn,other.isbn);
    

使用== 比较对象引用。通常当你重写你的 class 中的 equals 方法来比较你的 class 中的两个对象时,最好先使用引用 equal。这将避免比较对象内的所有属性。 考虑示例 Cat class

public class Cat {
 String country;
 int numberOfCats;
 public Cat(String country, int numberOfCats) {
    this.country = country;
    this.numberOfCats = numberOfCats;
 }
 public boolean equals(Object obj) {
    if(this == obj)
        return true;
    if(obj == null)
        return false;
    Cat eqlObj = (Cat) obj;
    if(this.country.equals(eqlObj.country) && this.numberOfCats == eqlObj.numberOfCats)
        return true;    
    return false;
 }
}

测试class

public class TestCat {
 public static void main(String args[]) {
    Cat obj1 = new Cat("France", 9600);
    Cat obj2 = obj1;
    obj1.equals(obj2);
 }
}

在上面的测试中class obj1 和obj2 都指向同一个Cat 对象。比较引用将 return "true",即首先 if 块中等于。

另一个测试

public class TestCat {
 public static void main(String args[]) {
    Cat obj1 = new Cat("France", 9600);
    Cat obj2 = new Cat("France", 9600);
    obj1.equals(obj2);
 }
}

在此测试中 class 为 obj1 和 obj2 创建了新对象,因此它们持有的引用将不同。对象中分配的值相同。首先,如果 equals 中的块将失败,因为引用不同。第三个 if 块中的 equals 将比较值和 return "true".

希望这对您有所帮助..