10

同一个对象的所有 JVM 实现的输出是否Object.hashCode()需要相同?

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

4

6 回答 6

20

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

但是,在您给出的具体示例中,值"test".hashCode() 实际上是一致的,因为对象的实现hashCodeStringAPI 的一部分String(请参阅java.lang.String 的 Javadocs其他 SO 帖子)。

于 2009-10-04T16:54:16.630 回答
6

从 API

hashCode 的一般合约是:

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

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

于 2009-10-04T16:45:11.073 回答
4

不, 的结果hashCode()仅在次执行期间保持不变。您不应该期望函数的结果在执行之间是相同的,更不用说在 JRE 版本或平台之间了。

于 2009-10-04T16:51:06.613 回答
0

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

在提到 String 类的具体实现时,不要依赖返回值。如果您的程序在不同的 VM 中执行,它可能会发生变化。

如果您仅提及 Sun Vm,则可能会争辩说 Sun 不会破坏现有代码——即使是编程错误的代码。因此对于任何版本的 Sun VM,“test”.hashCode() 将始终准确返回 3556498

如果您想故意向自己的脚开枪,请继续依靠这一点。需要修复在“2015 Nintendo Java VM for Hairdryer”上运行的代码的人会在晚上喊出你的名字。

于 2009-10-04T17:02:17.433 回答
0

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

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

尽管很难想出一个合理的现实世界的例子,但这并不能保证。

于 2009-10-04T17:11:50.923 回答
0

唯一的事实:应用程序运行的哈希码是相同的。另一次运行可能会给出其他哈希码。

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

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

0 – Park-Miller RNG(默认)

1 - f(地址,全局)

2 – 常数 1

3 – 顺序计数器

4 – 对象在堆中的地址

5 – Xorshift(最快)

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

于 2015-08-06T17:51:59.930 回答