为什么Object.hashCode()不遵循Java代码约定

时间:2014-10-04 19:46:00

标签: java hashcode coding-style

有什么特别的原因,为什么hashCode是Object类的唯一公共方法,它不遵循Sun推荐的Java代码约定以及后来的Oracle?我的意思是他们可以将它命名为toHashCode()或getHashCode()或createHashCode()对吗?

编辑: 我将讨论Java编程语言的代码约定(oracle.com/technetwork/java/codeconvtoc-136057.html)。 Oracle的书“OCA Java SE 7程序员I学习指南”(考试1Z0-803)(Oracle出版社) - Liguori,Robert'

中引用了这些约定。

document中,我们可以阅读如下: “方法应该是动词,混合情况下 第一个字母小写,第一个字母 每个内部词都大写。“。

AFAIK哈希码不是动词。

2 个答案:

答案 0 :(得分:6)

我认为 遵循惯例。这完全取决于你正在谈论的

OP对Code Conventions for the Java Programming Language特别感兴趣,方法名称的约定在chapter 9中有所涉及。首先,应该注意的是,该文档不再被维护,并且包含一个很大的警告:

  

......信息本身可能不再有效。该文件的最新修订版于1999年4月20日作出。

当然,hashCode()方法早于1999年,因此我们可以引用该文档,以查看该方法是否违反了当时的约定。该文件指出:

  

方法应该是动词,混合大小写,首字母小写,每个内部单词的首字母大写。

关于hashCode(),没有争议是与第一个字母小写的混合大小写。但是,OP似乎认为它违反了方法应该是动词的惯例;隐含的假设是“哈希码”或“哈希码”是名词。

在通过判断之前,让我们看一下约定的第三部分: 每个内部词的第一个字母 [is]大写。如果您简单地假设原作者遵循这些约定,那么hashCode()的大小写表明其作者认为“哈希”和“代码”是单独的词。如果您单独处理它们,“hash”一词是英语中的动词。通过这种解释,符合公约的所有部分。

不可否认,术语“哈希代码”已成为(至少)Java开发人员的常用术语,并且通常被视为名词 - 可能在很大程度上归因于此方法的名称。 (鸡与蛋?)但只有原作者可以说出他们的意图


在我的原始答案中,我使用JavaBeans约定作为示例:

  

bean是一个Java类,其方法名称遵循JavaBeans准则。 bean构建器工具使用内省来检查bean类。基于此检查,bean构建器工具可以找出bean的属性,方法和事件。

在JavaBeans中,通过“getter”方法访问属性,即通过调用getFoo()来读取“foo”属性。但是,<{hashCode()方法是{语言强加于Object的所有子类的技术要求,但通常不是属性对象表示的“业务逻辑”。如果你编写一个类来表示水果,它将具有getColor()isSkinEdible()等属性。如果不是Java的技术要求,你可能不会考虑编写方法比如getHashCode(),因为......你有没有找到一个带有哈希码的真实香蕉?

如果hashCode()被命名为getHashCode()那么,对于这个约定,JavaBeans必须特殊情况才能忽略它。或者它总是会检查“属性”,因为它通常在程序的主要逻辑中没什么用处。


我无法涵盖这个答案中的所有可能的约定,但我对这个问题中给出的其他例子有这些想法:

  • createHashCode() - 即使按惯例,我也不会使用此功能,因为hashCode()会返回int(原语)并且它们不是创建的就像引用类型(Objects)一样。我认为这是错误的动词。

  • toHashCode() - 对我而言,这代表了转化。但这不是hashCode()的作用。如果foo.hashCode()返回42,我不应期望42以任何方式表示foo。它是根据关于 foo实例的信息计算出来的,但没有其他真正的相关性。许多其他实例(许多类)都可以返回42,因此它不是替代它们的替身或模拟。

答案 1 :(得分:5)

在有约定之前指定了hashCode()方法。

此外,惯例是命名Java Bean&#34;属性,&#34;便于在设计工具中将bean连接在一起,并协助其他形式的自动化。在这些情况下,您不太可能需要将哈希码公开为属性。事实上,因为getClass()遵循Java Bean命名约定,所以在许多此类工具中需要一个特殊情况才能将其从对象属性列表中排除。