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 值这个规则就可以”。

扫描二维码关注公众号,回复: 11440716 查看本文章

举个例子来说,计算 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开发者做事,没什么毛病~

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

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

猜你喜欢

转载自www.cnblogs.com/christmad/p/13379061.html
今日推荐