类比较方法java中的class compare与instanceof

时间:2018-01-28 19:53:25

标签: java spring object entity equals

喜欢标题: 我的实体看起来像这样:

@Entity
public class Example {

    @Id
    private Integer id;
    private String name;

    // fields, getters & setters ommited 

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Example example = (Example) o;

        return id != null ? id.equals(examle.id) : examle.id == null;
    }

    @Override
    public int hashCode() {
        return id != null ? id.hashCode() : 0;
    }
}

自动生成的equals方法如上所示。

我的问题是:

  1. 为什么我需要手动更换:
  2.   

    o == null || getClass()!= o.getClass()

      

    !(o instanceof   实施例)

    1. 如果此类的对象放在java.util.Set中会发生什么?合同规则将在何种程度上受到侵犯?

2 个答案:

答案 0 :(得分:2)

主要区别在于,如果o具有对象的继承,则instanceof将返回true,而getClass比较将检查两个对象是否都是严格相同的类。

答案 1 :(得分:1)

根据经验,在您自己的班级中,使用

几乎总是更好
if (o == null || getClass() != o.getClass()) return false;

当您计划创建班级的子类并覆盖equals时,尤其如此,当您还没有计划这将无问题时(在大多数情况下)。所以你不需要手动更换任何东西。

原因如下。 equals方法需要在对象上引入等价关系,特别是它应该是对称的:如果a.equals(b)它也必须是b.equals(a)的情况,反之亦然。许多使用equals方法的类(如地图和集合)都会采用此行为。

现在,假设您将o == null || getClass() != o.getClass()替换为!(o instanceof Example),并创建一个子类a:

class Subclass extends Example {
    String address;
    // fields, getters and setters
    public boolean equals(Object o) {
        if (!o instanceof Subclass) {
            return false;
        } else {
            return super.equals(o) && Objects.equals(((Subclass)o).address, address);
        }
    }
}

现在考虑以下代码:

Example a = new Example(); 
a.setId(1);
a.setName("A");
Subclass b = new Subclass();
b.setId(1);
b.setName("A");
b.setAddress("Street 1");
System.out.println(a.equals(b)); // Prints true
System.out.println(b.equals(a)); // Prints false

您现在有一个不对称的equals方法,这可能会在使用集合时导致问题。

但请注意,在某些案例中,您实际上想要使用instanceof。例如,接口equals的{​​{1}}方法的Javadoc指定当两个集合包含相同的元素时,它们是相等的。因此,如果Set包含相同的元素,则HashSet等于TreeSet,即使这两个属于不同的类。当然,在这种情况下,使用getClass() == o.getClass()

是不合适的