Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重写equals和hashCode只是为了调用super.equals/hashCode或抛出断言错误?_Java - Fatal编程技术网

Java 重写equals和hashCode只是为了调用super.equals/hashCode或抛出断言错误?

Java 重写equals和hashCode只是为了调用super.equals/hashCode或抛出断言错误?,java,Java,是否有最佳实践,何时覆盖equals 我应该重写equals/hashCode并抛出断言错误吗?只是为了确保没人用它?(如《有效Java》一书中所推荐) 我是否应该重写equals/hashCode并只调用super.equals/hashCode,因为超类的行为与我们想要的相同?(FindBugs建议这样做,因为我添加了一个字段) 它们真的是最佳实践吗?错误 您不应该从equals或hashCode方法引发异常。equals和hashCode方法在任何地方都会使用,在这里不加区分地抛出异常可能

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

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

我是否应该重写equals/hashCode并只调用super.equals/hashCode,因为超类的行为与我们想要的相同?(FindBugs建议这样做,因为我添加了一个字段)

它们真的是最佳实践吗?

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

断言错误

决不能直接抛出断言错误。将
assert
语句放入任何方法都可以,因为在关闭断言时不会运行这些语句

何时覆盖 如果超级类方法是
Object.equals
,那么重写并直接传递到
super.equals()
是无害的

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

最佳做法 在这里是一个很好的资源,特别是关于如何最好地实现
hashCode()
方法。确保您阅读并考虑了Javadoc中列出的和的合同,并确保是否覆盖其中一个,然后覆盖另一个。eclipse中的“Generate hashCode()and equals”函数很好地提供了这些方法中所需的内容,因此请查看它为类生成的代码。以下内容摘自

  • 它是自反的:对于任何非空参考值x,x.equals(x)应该返回true
  • 它是对称的:对于任何非空的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true
  • 它是可传递的:对于任何非空引用值x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)应该返回true
  • 它是一致的:对于任何非空的引用值x和y,x.equals(y)的多次调用始终返回true或false,前提是没有修改对象上equals比较中使用的信息
  • 对于任何非空引用值x,x.equals(null)应返回false

  • 在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须始终返回相同的整数。从应用程序的一次执行到同一应用程序的另一次执行,该整数不必保持一致
  • 如果根据equals(Object)方法两个对象相等,那么对两个对象中的每一个调用hashCode方法必须产生相同的整数结果
  • 根据equals(java.lang.Object)方法,如果两个对象不相等,则对这两个对象中的每一个调用hashCode方法都必须产生不同的整数结果,这不是必需的。但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能

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

重写
equals
hashCode
,然后使用
super.equals()调用超类实现
对我来说,这只是一种非常清晰的方式,可以证明您已经考虑过它,并且认为超级类实现仍然是完全有效的。就个人而言,我认为在类JavaDoc中记录这一点并跳过添加equals&hashCode没有任何问题

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


如果您正在扩展的对象确实支持相等,那么最好自己支持它,方法是调用super.equals(),然后比较您添加的其他成员。

我覆盖将在java.util Collections API中使用的所有对象的相等和哈希代码。这些类通常依赖于正确的重写。

我刚刚看到了krock写的东西,这让我想起了equals和hashCode的API。您应该遵循这些方法的API规范,而不是抛出意外的异常。有效的Java建议在非常有限的场景中抛出AssertionError:“类是私有的或包私有的,您可以确定它的equals方法永远不会被调用。”重写一个只调用超类方法的方法与不重写该方法是一样的。我不同意以下几点:(1)如果参数为null,那么equals的结果应该是“false”,而不是NPE;(2)检查