jdk源码学习之: Object#equals() 和 Object#hashCode()

equals 和 hashCode 这两个方法,我见过的面试被问的最多也是我感觉最怪的问题是:“重写了某个方法,另一个方法要不要重写?是不是一定要重写?为什么?”

直到最近复习时整理了一下这两个方法的 java doc,从中发现了其奥秘。

先贴上我翻译的两个方法的注释版本吧:

由以上内容可知,jdk文档中明确声明的只有 Object#equals 方法提及了当该方法被重写(overridden)时可能需要重写 hashCode 方法。

为什么是可能?看下原文“it is generally necessary to override the hashCode method”,generally necessary 意思就是“一般来说都需要”,用了“generally”没有用“must”,可能性程度已经降低一个档次了。并且原文注释提到 overridden 的后半句还提到“so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.”,译为“只要能保证 equals 比较为相等的两个对象有相同的 hashCode 值这个规则就可以”。

举个例子来说,计算 hashCode 时取对象中有代表性的 3个属性,而 equals 方法中用了 5个属性,比 hashCode 方法的 3个属性多 2个。然后现在改成 equals 中再增加 1个属性,变成使用 6个属性来对比,但原来的 5个属性(hashCode 用的 3个包含在里面)并没有变,此时 hashCode 方法无需修改。

举这个例子灵感来源于两个方法注释中都有的一句(其特指 equals 方法):“provided no information used in equals comparisons on the object is modified”。我将之翻译为“这规定了在 equals 方法中不要使用那些易变的属性来做对比。”

这句注释当年看了很多遍都没理解。

最近复习查了词典,发现 provide 居然还有“规定”这个意思,然后重新翻译了一遍才有了如上的版本。

翻译过程如下:有了“规定”这个意思以后,把后面的句子重新组装一下,后半句不带 provide 直译就是“在 object 变化的时候没有任何(有变化的)信息在 equals 方法的对比过程中使用到”。

这里 provide 的翻译就至关重要了,N年前后半句我已经可以翻译出来,只是 provide 按“提供”去理解的话,就非常怪了。而有了“规定”这个意思,结合在 hashCode 里看到的 contract(协议,契约)一词,联想起来相对较为通顺了些,协议里面这规定那规定的是很正常的事~

而“规定”有时也能理解为“别人在教你做事”,JDK开发者教Java开发者做事,没什么毛病~

没想到经过多年学习,知道英文也有一词多义后,居然在此次复习中“温故而知新了”。妙啊~

其他的点如翻译所示,就不再啰嗦了。

原文地址:https://www.cnblogs.com/christmad/p/13379061.html