equals() 总合同的哪一部分不满足我的 equals()

2022-09-03 02:20:01

我对Java相当陌生,我只是想让我的头脑理解和方法。
我知道要使等式方法正确,它需要是:@Overrideequals()hashcode()

  1. 反身: a.equals(a)
  2. 对称:然后a.equals(b) b.equals(a)
  3. 可传递:a.equals(b) && b.equals(c) a.equals(c)
  4. 不为空: ! a.equals(null)

我正在努力确定在编写我的 equals 方法时,我是上述哪些属性,哪些是不令人满意的。

我知道日食可以为我生成这些,但是由于我还没有完全理解这个概念,写出来可以帮助我学习。

我已经写出了我认为正确的方法,但是当我检查日食生成的版本时,我似乎“遗漏”了一些方面。

例:

public class People {

    private Name first; //Invariants --> !Null, !=last
    private Name last;  // !Null, !=first
    private int age;    // !Null, ! <=0
    ...
}

我写了:

public boolean equals(Object obj){
    if (obj == null){
        return false;
    }
    if (!(obj instanceof People)){
         return false;
    }
    People other = (People) obj;
    if (this.age != other.age){
        return false;
    }
    if (! this.first.equals(other.first)){
        return false;
    }
    if (! this.last.equals(other.last)){
        return false;
    }
    return true;
}

日食生成的对比

public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;

    People other = (People) obj;
    if (first == null) {
        if (other.first != null)
            return false;
    } else if (!first.equals(other.first))
        return false; 
    if (age != other.age)
        return false;
    if (last == null) {
        if (other.last != null)
            return false;
    } else if (!last.equals(other.last))
        return false;

    return true;
}

我错过了:

  • if (this == obj)
        return true;
    
  • if (getClass() != obj.getClass())
        return false;
    
  • 对于每个变量:

    if (first == null) {
        if (other.first != null)
            return false;
    } else if (!first.equals(other.first))
        return false;
    

我不确定什么是,我的暗示不正确?getClass()


答案 1

第一段代码:

if (this == obj)
    return true;

这样可以提高性能,以防您将对象引用与自身进行比较。例:。a.equals(a);

第二段代码:

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

如果被比较的引用的类与 的类相同,则将进行比较。使用此方法与使用此方法之间的区别在于,在与子类进行比较时,它的限制性更强。例:thisinstanceof

public class Foo { }
public class Bar extends Foo { }

//...
Foo foo = new Bar();
System.out.println(foo instanceof Bar); //prints true
System.out.println(foo instanceof Foo); //prints true
Foo foo2 = new Foo();
System.out.println(foo.getClass() == foo2.getClass()); //prints false

您应该选择哪一个?没有好或坏的方法,这取决于你想要的设计。

第三段代码:

if (first == null) {
        if (other.first != null)
            return false;
    } else if (!first.equals(other.first))
        return false; //For each variable.

这只是对类中每个对象引用字段的空检查。请注意,如果 是 则 执行 将抛出 .this.firstnullthis.first.equals(...)NullPointerException


答案 2

我不认为你的实现是不正确的,但需要注意一些:

if (this == obj)
      return true;

是一种性能优化,它直接测试参考相等和短路测试的地方aa

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

类似于您的调用,优化空检查。其他调用似乎是空检查。instanceof


推荐