Overriding the equals method vs creating a new method我一直认为应该重写Java中的.equals()方法,使其特定于您创建的类。 换句话说,要寻找两个不同实例的等效性,而不是对同一实例的两个引用。 但是,我遇到了其他程序员,他们似乎认为默认对象的行为应该保留下来,并创建一个新方法来测试同一类的两个对象的等效性。 支持和反对覆盖equals方法的论点是什么? 如果要在标准库类中测试等效性,则必须重写equals方法(例如,确保java.util.Set包含唯一元素或将对象用作java.util.Map对象中的键)。 请注意,如果您覆盖等号,请确保遵守文档中所述的API合同。例如,确保您还重写Object.hashCode:
编辑:我没有将其发布为关于该主题的完整答案,因此,我将回应弗雷德里克·卡尔塞斯(Fredrik Kalseth)的说法,即重写等于最适合不可变对象。引用Map API:
我强烈建议您选择《有效Java》的副本,并遵循平等合同通读第7项。如果要覆盖可变对象的相等值,则需要小心,因为诸如Maps和Sets之类的许多集合都使用相等值来确定等效性,并且对集合中包含的对象进行变异可能会导致意外结果。 Brian Goetz还对实现equals和hashCode进行了很好的概述。 对于可变对象,您不应"永远"覆盖equals和getHashCode-这适用于.net和Java。如果这样做,并在f.ex字典中使用此类对象作为键,然后更改该对象,则会遇到麻烦,因为字典依赖哈希码来查找对象。 这是一篇有关该主题的好文章:http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx @David Schlosnagle提到了乔什·布洛赫(Josh Bloch)的《有效的Java》-这是任何Java开发人员都必须读的书。
有一个相关的问题:对于不可变的值对象,您还应该考虑覆盖
老实说,在Java中并没有真正反对覆盖相等的论点。如果您需要比较实例是否相等,那就是您要做的。 如上所述,您需要了解与hashCode的约定,并且类似地,请注意Comparable接口周围的陷阱-在几乎所有情况下,您都希望由Comparable定义的自然顺序与equals保持一致(请参阅BigDecimal api doc(用于规范计数器示例) 除了不使用现有的库类之外,创建一种用于确定相等性的新方法还需要面对Java约定。
如果在将对象添加到排序的数据结构(
这样做时,您还应该覆盖 请参阅此处以获取完整说明。 Equals方法旨在比较引用。因此,不应改变它来更改其行为。 如果需要,您应该创建一个新方法来测试不同实例中的等效性(或在某些.NET类中使用CompareTo方法) |