何时应该重写Equals函数?

22

可能有重复:
Java:始终覆盖equals吗?

我创建的任何类都应该覆盖equals函数吗?

即使对于仅包含一些非常简单属性的简单类,通过equals我需要每个属性都相等吗?

3个回答

35
我应该为我创建的任何类重写equals函数吗?
只有当对象“表示某些数据”,即如果它建模诸如Person、Car或RecipieIngredient之类的东西(这些通常最终出现在集合中)时,才覆盖equals。不要为其他类型的类覆盖equals,例如LoginServlet或DatabaseUtil。
请记住,每当您覆盖equals时,始终要覆盖hashCode。
(一个自然的后续问题:)如果我不覆盖equals和hashCode会发生什么?
除非它们是完全相同的对象,否则任何两个对象都将被视为不相等。
[...] 我需要它的每个属性都相等吗?

通常是这样的是的。这取决于您如何定义平等的概念。请注意,对于引用类型,您可以在实现自己的equals(和hashCode)时重用/委托给对象的实现。

相关问题:


1
+1 不能再说得更好了,简单而漂亮的解释。 - posdef

16

只有在有充分理由的情况下才应该覆盖 equals() 方法。如此处所述,对于非 final 或可变类编写正确的 equals() 方法非常困难。

如果您的应用程序需要一些不同于“相同对象”的等价概念,那么可以这样做。只需阅读上述参考文献以了解相关内容。但作为常规操作?绝对不是。


3

如果您用生活中的术语来理解,就更容易理解覆盖equals()的概念。

只有当两个对象在逻辑上需要相等时,才应该覆盖Equals方法。此外,如果您担心程序中某个对象可能会被重新创建,则必须覆盖equals()。

Java中一个很好的例子是字符串对象。

   String string1= new String("hello");

   String string2= "hello";

他们相等吗?.. 是的,从逻辑上讲,它们是相等的。你能够检查它们的相等性,只因为Java已经重写了String equals()方法。
众所周知,类实际上是其对象的模板。那么,让我们考虑一个员工类,它确定公司中雇员可能拥有的属性,而公司中的实际雇员是该类的对象。因此,雇员的属性通常如下:
1. 员工姓名
2. 员工ID
3. 出生日期 . . . .. .
在这种情况下,你应该只检查equals方法中的Employee ID是否相等。但是,如果你的对象缺少这种明显的属性,那么你就需要检查几乎所有值,以避免使你的程序认为两个不同的人相等。

+1,好答案。不过关于你最后的观点,有一些需要注意的地方。如果一个员工是可变的,检查某个员工的ID的方法可能会有风险。 - aioobe
嗯...如果某些东西是可变的,那么你就完全失去了控制。整个equals()世界都会失败。 - Ahmad
你这样做的理由是什么? - aioobe
嗯...你担心如果它是可变的,那么员工ID将不一致..那么..还有什么可以保证相等性.. - Ahmad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接