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

kuk*_*kis 4 java coding-style hashcode

是否有任何特定的原因,为什么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'中引用了这些约定.

文档中我们可以读作如下:"方法应该是动词,大小写混合,第一个字母小写,每个内部单词的首字母大写."

AFAIK哈希码不是动词.

Wil*_*ice 6

我认为它确实遵循惯例.这一切都取决于你所谈论的约定.

OP 对Java编程语言代码约定特别感兴趣,方法名称的约定在第9章介绍.首先,应该注意的是,该文档不再维护,并且包含一个很大的警告:

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

当然,该hashCode()方法早于1999年,因此我们可以参考该文档,看看当时有关方法是否违反了这些惯例.该文件指出:

方法应该是动词,在第一个字母小写的大小写混合的情况下,每个内部单词的首字母大写.

关于hashCode(),没有争议是它与首字母小写的混合情况.但是,OP似乎认为它违反了方法应该是动词的惯例; 隐含的假设是"哈希码"或"哈希码"是名词.

在通过判断之前,让我们看一下约定的第三部分:每个内部词的第一个字母是[大写].如果您简单地假设原作者遵循这些约定,则大写hashCode()表示其作者将"哈希"和"代码"视为单独的词.如果你单独对待它们,"hash" 这个词就是英文的动词.通过这种解释,符合公约的所有部分.

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


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

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

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

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


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

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

  • toHashCode() - 对我来说,这代表了转换.但那并不是什么hashCode()意思.如果foo.hashCode()回报42我不应该42以任何方式表达foo.它是根据有关foo实例的信息计算出来的,但没有其他真正的相关性.许多其他实例(许多类)都可以返回,42所以它不是替代它们的替身或模拟.


eri*_*son 5

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

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

  • 如果`class`不是Java关键字,你可以打赌这个方法将命名为`class()`. (3认同)