大家好,请让我知道,在现实世界中,为什么我们需要重写equals和hashCode方法,不能使用Object类提供的equals和hashCode方法。
如果你想要“引用标识”作为对象相等的标准,那么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
实现如何知道FileInputStream
和String
所需行为上的差异呢?它可能会注意到添加到字段、属性和类型本身的注释,可能会自动生成适当的字节码,然后获得JIT编译...但是当然,在注释可用之前Java已经问世。当前的方法非常简单-但这意味着,如果您想要不同对象的值相等,则需要自己编写代码。
值得注意的一点是,对于不可变类型,相等通常更容易考虑-如果两个对象在某一时间点相等,然后在以后不相等,这很奇怪。这也可能会严重破坏哈希表-哈希码应基本上取决于被视为相等的对象方面,而哈希码在第一次添加键到哈希表时记录;如果您然后更改键的内容,其哈希码将更改,但哈希表不会知道。
在现实世界中,如果您使用对象的实现方式
new Integer( 1 )
不等于 new Integer( 1 )