有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java重写equals和hashCode只是为了调用super。等于/哈希代码还是抛出断言错误?

是否有最佳实践,何时覆盖equals

我应该重写equals/hashCode并抛出断言错误吗?只是为了确保没人用它?(如《有效Java》一书中所推荐)

我应该重写equals/hashCode并调用super吗。equals/hashCode,因为超类行为与所需的相同?(FindBugs建议这样做,因为我添加了一个字段)

它们真的是最佳实践吗


共 (4) 个答案

  1. # 1 楼答案

    我为java中使用的所有对象重写equals和hashCode。util集合API。这些类通常依赖于适当的重写

  2. # 2 楼答案

    重写equalshashCode,然后用super.equals()调用超类实现,这是一种非常清晰的方式,可以证明您已经考虑过它,并且认为超类实现仍然完全有效。就我个人而言,我认为在类JavaDoc中记录这一点并跳过添加equals&;哈希代码

    抛出断言错误有点极端,不太符合最小惊喜原则。如果在对象上调用equals()hashCode()确实是一个错误,请使用UnSupportedOperationException

    如果你正在扩展的对象确实支持平等,那么最好通过调用super来支持它。equals(),然后比较添加的其他成员

  3. # 3 楼答案

    如果需要比较同一类中的两个对象,应该使用自己的实现重写equals。如果要重写equals,那么还应该为hashCode提供一个实现。仅仅为了调用super而重写这些方法是没有意义的,因为这是默认行为。我不会重写抛出AssertionError的方法,因为这意味着您永远无法比较对象是否相等,或者在HashMap中使用它们。在这种情况下,Collections类还有其他含义

  4. # 4 楼答案

    错误

    您不应该从equalshashCode方法引发异常。equals和hashCode方法在任何地方都会使用,在这里不加区分地抛出异常可能会在以后对您造成伤害

    断言错误

    你不应该直接扔AssertionError。将assert语句放入任何方法中都可以,因为在关闭断言时,这些语句将不会运行

    何时覆盖

    如果超类方法是Object.equals,那么重写并直接传递给super.equals()是无害的

    如果你正在比较的两个对象是不同类型的,那么你可能会陷入对称性破缺的陷阱,即x.equals(y)为真,而y.equals(x)为假。如果y是x的一个子类,则可能会发生这种情况,因此y的equals方法可能会进行稍微不同的比较。您可以使用if (getClass() != obj.getClass()) return false;在equals方法中检查这一点

    最佳实践

    Effective Java在这里是一个很好的资源,尤其是关于如何最好地实现hashCode()方法。确保阅读并考虑了Javadoc中列出的equalshashCode的合同,并确保如果覆盖其中一个,那么覆盖另一个。eclipse中的“Generate hashCode()and equals”函数很好地提供了这些方法中所需的内容,所以请查看它为类生成的代码。以下内容摘自Javadoc of java.lang.Object

    equals Contract:

    • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
    • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
    • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
    • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
    • For any non-null reference value x, x.equals(null) should return false.

    hashCode Contract:

    • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
    • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
    • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.