哪种等于方法更优选?

时间:2017-07-18 22:01:37

标签: java

另一个奇怪的问题,我有两个equals方法的实现 实施更为可取,为什么?

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

        Test other = (Test) o;

        return id == other.id;

    }

或者这个,

@Override
public boolean equals(Object o) {
    if (o instanceof Test) {
       Test other = (Test) o;
       return id == other.id;
}
 return false;
}

请注意,课程不是最终的。

1 个答案:

答案 0 :(得分:2)

编辑:我希望id这里是原始的,否则你应该使用id.equals

取决于你的目标(只是在这里评估功能 - 如果你想要性能,你应该在真实场景中尝试,差异很可能是微不足道的。)

您的第一个案例:测试getClass() == o.getClass()。这是一个严格的类型等价,在处理子类时很有用。使用此模式,子类型实例永远不会等于超类型实例,反之亦然(但是,子类型仍然可以调用super.equals来测试父字段等效性)。这是我看到的通常模式,它允许子类型定义更具体的equals语义,比较更多字段(更多内容见下文)。

您的第二个案例:测试o instanceof Test。值得注意的是,这意味着Test实例测试等效于Test子类型实例,只要它们与id中的原始实例匹配即可。 Java equals应该以对称和传递的方式实现;这意味着如果this.equals(o),那么o.equalsthis.equals必须在功能上相同,即使oTest子类型的实例 EM>

这通常用于接口/契约级别的equals语义 - 例如,List s,SetMap定义等价的概念所有子类型必须满足,以便可以将不同的List实现相互比较。

[编辑:在这种情况下,.equals.hashCode都应该是最终的,以防止子类型重新定义语义 - 感谢@yshavit。]

TLDR:如果您不确定,请使用第一个,除非您非常确定您需要第二个。