另一个奇怪的问题,我有两个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;
}
请注意,课程不是最终的。
答案 0 :(得分:2)
编辑:我希望id
这里是原始的,否则你应该使用id.equals
。
取决于你的目标(只是在这里评估功能 - 如果你想要性能,你应该在真实场景中尝试,差异很可能是微不足道的。)
您的第一个案例:测试getClass() == o.getClass()
。这是一个严格的类型等价,在处理子类时很有用。使用此模式,子类型实例永远不会等于超类型实例,反之亦然(但是,子类型仍然可以调用super.equals
来测试父字段等效性)。这是我看到的通常模式,它允许子类型定义更具体的equals
语义,比较更多字段(更多内容见下文)。
您的第二个案例:测试o instanceof Test
。值得注意的是,这意味着Test
实例将测试等效于Test
子类型实例,只要它们与id
中的原始实例匹配即可。 Java equals
应该以对称和传递的方式实现;这意味着如果this.equals(o)
,那么o.equals
和this.equals
必须在功能上相同,即使o
是Test
子类型的实例 EM>
这通常用于接口/契约级别的equals
语义 - 例如,List
s,Set
和Map
定义等价的概念所有子类型必须满足,以便可以将不同的List
实现相互比较。
[编辑:在这种情况下,.equals
和.hashCode
都应该是最终的,以防止子类型重新定义语义 - 感谢@yshavit。]
TLDR:如果您不确定,请使用第一个,除非您非常确定您需要第二个。