【问题标题】:Dont understand this implementaion of equals method不明白equals方法的这个实现
【发布时间】:2016-04-06 12:41:06
【问题描述】:

几天前,我的教授向我们展示了如何实现 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 具有相同的引用(这就是 == 运算符的作用?只比较两个引用)

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

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

【问题讨论】:

  • 如果两个引用相同,那么它是一个对象,而不是两个。
  • 您的教授没有在他的 if 语句中使用大括号?哇。另外:Objects.equals 已经检查了引用和空值。

标签: java oop methods equals


【解决方案1】:

如果被比较的两个对象具有相同的引用,那么这是同一个对象,没有必要比较其他任何东西。您可以立即返回true 并保存一些比较。

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

【讨论】:

  • 嗯,但如果我写等于,我们会检查所有字段是否相同?这只会检查参考?
  • @MiljanRakita 仅在引用相等时才检查引用。否则,它将继续进行其余的检查。
  • 所以如果引用相等,这个方法会返回 true 吗?这和我们只使用 someOb == otherOb 而不是使用这个 equals 方法一样, someOb.equals(otherOb) 因为它们现在都只检查引用?
  • 如果只有所有字段都相同,则不是同一个对象(更好:实例)。您可以拥有两辆具有相同品牌、颜色、电机、车轮等的汽车,但实例仍然不同。例如,如果您制作了一份汽车文件的副本,然后将副本交给了其他人,那么这两份副本指的是完全相同的实例
  • @MiljanRakita 解释这一点的简单方法类似于 devnull69 所说的。您可以和您的朋友拥有同一辆车。它们可以同时从同一个经销商处以相同的颜色、型号、年份等购买,但它们每个都有一个唯一的车辆识别号。这个 VID 类似于程序用来识别对象的东西。当且仅当这些对象具有相同的 ID(IE,它们是完全相同的对象)时,== 运算符才返回 true。
【解决方案2】:

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

如果这两个 if 子句都不为真

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

这意味着这两个对象都来自同一个类,但不是同一个对象,那么那么与

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

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

【讨论】:

    【解决方案3】:

    考虑以下代码:

        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 Interning

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

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

    【讨论】:

      【解决方案4】:

      你的代码equals方法的逻辑:

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

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

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

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

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

      【讨论】:

        【解决方案5】:

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

        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;
         }
        }
        

        测试类

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

        在上面的测试类中,obj1 和 obj2 都指向同一个 Cat 对象。比较引用将返回“true”,即第一个 if block in equals。

        另一个测试

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

        在这个测试类中,为 obj1 和 obj2 创建了新对象,因此它们持有的引用将不同。在对象中分配的值是相同的。首先,如果等号中的块将失败,因为引用不同。第三个 if 块中的 equals 将比较值并返回“true”。

        希望这会有所帮助..

        【讨论】:

        • 谢谢,帮了大忙!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-28
        • 2019-08-22
        • 1970-01-01
        • 2012-10-01
        • 1970-01-01
        • 2023-03-25
        相关资源
        最近更新 更多