Java,Object.hashCode()结果常量跨所有JVM/系统?

Java,Object.hashCode()结果常量跨所有JVM/系统?,java,hashcode,Java,Hashcode,Object.hashCode()的输出是否要求在同一对象的所有JVM实现上都相同 例如,如果“test”.hashCode()在1.4上返回1,它可能会返回运行在1.6上的2。或者,如果操作系统不同,或者实例之间存在不同的处理器体系结构,该怎么办 来自API hashCode的总合同为: 在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须始终返回相同的整数。从应用程序的一次执行到同一应用程

Object.hashCode()
的输出是否要求在同一对象的所有JVM实现上都相同

例如,如果
“test”.hashCode()
在1.4上返回
1
,它可能会返回运行在1.6上的
2
。或者,如果操作系统不同,或者实例之间存在不同的处理器体系结构,该怎么办

来自API

hashCode的总合同为:

  • 在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须始终返回相同的整数。从应用程序的一次执行到同一应用程序的另一次执行,该整数不必保持一致
  • 如果根据equals(Object)方法两个对象相等,那么对两个对象中的每一个调用hashCode方法必须产生相同的整数结果
  • 根据equals(java.lang.Object)方法,如果两个对象不相等,则对这两个对象中的每一个调用hashCode方法都必须产生不同的整数结果,这不是必需的。但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能

只要是合理可行的,类对象定义的hashCode方法确实会为不同的对象返回不同的整数。(这通常是通过将对象的内部地址转换为整数来实现的,但JavaTM编程语言不需要这种实现技术。)

否,
hashCode()
的结果在单个执行过程中仅为常量。您不应该期望函数的结果在执行之间是相同的,更不用说在JRE版本或平台之间了。

否。
hashCode
的输出在JVM实现之间,甚至在同一JVM上的不同程序执行之间,都可能发生变化


但是,在您给出的特定示例中,
“test”.hashCode()
的值实际上是一致的,因为
String
对象的
hashCode
实现是
String
API的一部分(请参见和)。

首先,hashCode的结果在很大程度上取决于对象类型及其实现。每个类(包括其子类)都可以定义自己的行为。您可以根据javadoc以及其他答案中概述的总合同来信赖它。但是,在VM重新启动后,不要求该值保持不变。特别是当它依赖于第三方类的.hashCode实现时

在引用String类的具体实现时,不应依赖于返回值。如果您的程序在不同的VM中执行,它可能会发生更改

如果您只提到Sun Vm,可能会有人认为Sun不会破坏现有的代码(即使编程很糟糕)所以“test”.hashCode()对于任何版本的Sun VM都将始终精确返回3556498


如果你想故意朝自己的脚开枪,那就靠这个吧。需要修复您在“2015 Nintendo Java VM for Heartriver”上运行的代码的人会在晚上喊出您的名字。

如前所述,对于许多实现,hashCode()的默认行为是返回对象的地址。显然,每次运行程序时,这可能会有所不同。这也与equals()的默认行为一致:两个对象仅当它们是同一个对象时才相等(其中x和y都是非null,x.equals(y)当且仅当x==y)

对于覆盖hashCode()和equals()的任何类,它们通常是基于部分或所有成员的值以确定性方式计算的。因此,在实践中,如果程序的一次运行中的一个对象可以说等于程序的另一次运行中的一个对象,并且源代码是相同的(包括String.hashCode()的源代码,如果hashCode()重写调用了该源代码),则哈希代码将是相同的


虽然很难想出一个合理的现实例子,但这并不能保证

唯一的事实是:hashcode对于应用程序运行是相同的。另一次运行可能会产生其他哈希代码

当您请求对象的哈希代码时,JVM使用一种RNG算法创建它,并将其放入对象的头中以备将来使用。 只需查看OpenJDK中的函数

RNG算法可通过JVM arg-XX:hashCode=x配置, 其中x是一个数字:

0–停车场米勒RNG(默认值)

1-f(地址,全球)

2–常数1

3–顺序计数器

4–堆中对象的地址

5–Xorshift(最快)


当hashcode等于堆中的地址时——这有时很尴尬,因为GC可以将对象移动到另一个堆单元等。

(尽管如果可以找到1.0 JDK,情况会有所不同。API文档中的错误定义在实现时实际上会引发异常。)对于大多数应用程序来说,它也是定义良好的collections@finnw:是的;对于同一应用程序,同一系统上同一版本的不同运行不需要hashCode返回相同的值,更不用说不同版本、不同系统或不同应用程序。标识哈希代码通常存储在对象标头(热点)中@马克:一个合理的例子是,您重写了
hashCode()
,并让hashCode计算包含一个组件对象的hashCode,该组件对象的
hashCode()
未被重写。这样做可以做到,但您将无法允许两个对象相等。两个“相等”的对象将具有不同的哈希代码。如果你把这样一个