为什么我们需要在Java中覆盖equals和hashCode方法,为什么不能使用Object类的实现?

4

大家好,请让我知道,在现实世界中,为什么我们需要重写equals和hashCode方法,不能使用Object类提供的equals和hashCode方法。


请重写Java中的equals和hashCode方法。 - skaffman
3
@skaffman:我认为“有哪些陷阱”和“为什么我们需要这样做”是不同的问题。 - Jon Skeet
@jon 是的,那就是我想要问的问题。 - Suresh S
2个回答

11

如果你想要“引用标识”作为对象相等的标准,那么Object的equals/hashcode实现就很好了。换句话说,一个对象始终与自身相等,但与另一个对象不同。

然而,如果你希望两个不同的对象相等,就必须重写该方法以确定它们应该如何相等(然后重写hashcode以保持一致)。

最简单的例子可能是String。具有相同字符的两个不同字符串是相等的,这对于它们相等非常有用:

String x = new String(new char[]{'a', 'b', 'c'});
String y = new String(new char[]{'a', 'b', 'c'});
System.out.println(x.equals(y)); // Prints true

现在将其与FileInputStream进行比较-什么会使两个FileInputStream相等?如果它们正在读取同一个文件?文件内的位置呢?或者对于具有相同内容的不同文件的两个流怎么处理?在我看来,这样问问题并没有太多意义。

那么,Object实现如何知道FileInputStreamString所需行为上的差异呢?它可能会注意到添加到字段、属性和类型本身的注释,可能会自动生成适当的字节码,然后获得JIT编译...但是当然,在注释可用之前Java已经问世。当前的方法非常简单-但这意味着,如果您想要不同对象的值相等,则需要自己编写代码。

值得注意的一点是,对于不可变类型,相等通常更容易考虑-如果两个对象在某一时间点相等,然后在以后不相等,这很奇怪。这也可能会严重破坏哈希表-哈希码应基本上取决于被视为相等的对象方面,而哈希码在第一次添加键到哈希表时记录;如果您然后更改键的内容,其哈希码将更改,但哈希表不会知道。


2

在现实世界中,如果您使用对象的实现方式

new Integer( 1 ) 不等于 new Integer( 1 )


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