繁体   English   中英

为什么 java.lang.Integer 上的实例方法 hashCode 会额外跳转到 static class 方法以简单地返回自己的 Z157DB7DF530023575515D366C9B672E8 值?

[英]Why does the instance method `hashCode` on `java.lang.Integer` make an extra jump to the static class method to simply return its own integer value?

我只是在探索 hashCode() 方法的不同实现。 我打开了 java.lang.Integer class 并找到了 hashCode() 的这个实现:

public int hashCode() {
        return Integer.hashCode(value);
}

public static int hashCode(int value) {
        return value;
}

我的问题是,为什么实现不能这么简单:

public int hashCode(){
    return this.value;
}

需要创建一个额外的 static 方法来传递值并返回相同的值吗? 我在这里忽略了任何重要的细节吗?

该代码在单独查看时确实看起来很奇怪。

但请注意 static 方法java.lang.Integer.hashCode

  • 后来添加,在Java 8
  • public

Java 14 中的源代码显示没有注释来解释为什么要添加这个 static 方法。 因为该方法是public ,所以我认为这个新的 static 方法在 Java 8 中的一些新特性中起作用,可能与流有关,在OpenJDK代码库的其他地方调用。

如 Javadoc 中所述,为了保持一致性,现有Integer::hashCode实例方法的源代码被重写为调用 static hashCode 这样,只有一个地方实际生成了 hash 代码。 对于代码库的审查和维护来说,只有一个地方是明智的。

制作hashCode static 肯定是不寻常的。 hashCode方法的目的是将 class 中的一个 object 识别到另一个 collections 中使用,例如HashSetHashMap 鉴于我们通过方法比较实例,因此将hashCode作为实例方法而不是 static 是有意义的。

HotSpotOpenJ9等优化编译器可能会内联hashCode方法调用,从而使源代码中的实例方法与静态方法排列变得毫无意义。

@Basil Bourque 的回答几乎涵盖了所有内容。 但他没有回答为什么要添加public static void hashCode(int)的问题。

2012 年 11 月在此变更集中进行了更改

变更集的标题和摘要是这样说的:

7088913:将兼容的 static hashCode(primitive) 添加到原始包装类

摘要:将 static 实用程序方法添加到每个基元包装器 class 以允许从未装箱的基元计算 hashCode 值。

请注意,变更集没有记录变更的动机。

我推断增强的一个目的是避免应用程序程序员必须知道原始包装类是如何计算的。 在 Java 8 之前,要为原始int计算与包装器兼容的 hash 代码,程序员必须编写

  int value = ...
  int hash = ((Integer) value).hashCode();  // Facially inefficient (depending on
                                            // JIT compiler's ability to get
                                            // rid of the box/unbox sequence)

或者

  int value = ...
  int hash = value;                         // Hardwires knowledge of how 
                                            // Integer.hashCode() is computed.

虽然“知识”对于int / Integer来说是微不足道的,但考虑double / Double的情况,其中 hash 代码计算为:

  long bits = doubleToLongBits(value);
  return (int)(bits ^ (bits >>> 32));

似乎这个变更集受到了 Streams 项目的推动。 例如, Integer::hashCode可以用于整数的 stream 中。

但是,添加summinmax以用于 stream 减少的变更集发生在此之后的几个月。 所以我们不能明确地建立联系……基于这个证据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM