4 回答
TA贡献1850条经验 获得超11个赞
您的代码正在对基元值进行装箱。(基元值本身没有标识哈希代码,因为这只是一个与对象相关的概念。您的代码等效于以下内容:
int xInt=5;
int yInt=5;
Integer xInteger = xInt;
Integer yInteger = yInt;
System.out.println(System.identityHashCode(xInteger));
System.out.println(System.identityHashCode(yInteger));
double double1=5;
double double2=5;
Double boxedDouble1 = double1;
Double boxedDouble2 = double2;
System.out.println(System.identityHashCode(boxedDouble1));
System.out.println(System.identityHashCode(boxedDouble2));
现在,如果你比较参考文献本身,你会发现这是真的,但却是错误的......所以准确地代表了这种关系。xInteger == yIntegerboxedDouble1 == boxedDouble2identityHashCode
框内整数引用引用同一对象的原因是缓存特定范围内的框内整数类型:
如果装箱值 p 是计算布尔型、char、短整型、整数型或长整型常量表达式 (§15.28) 的结果,并且结果为 true、false、“\u0000”到“\u007f”(包括)范围内的字符,或介于 -128 到 127(包括 128 和 127)范围内的整数,则设 a 和 b 是 p 的任意两次装箱转换的结果。总是 a == b 的情况。
在实践中,范围实际上可以更大,并且实现也可以缓存盒装双精度值,但我还没有看到这种情况发生。
TA贡献1772条经验 获得超8个赞
这里有一个拳击问题 - 您无法将原始数据类型与标识HashCode
进行比较,因为它用作其参数。Object
返回给定对象的哈希代码,与默认方法 hashCode() 返回的哈希代码相同
但当然与 .double
Double
TA贡献1859条经验 获得超6个赞
我了解到所有具有相同值的基元都具有相同的标识哈希代码。
那里至少有两个误解。首先,基元根本没有哈希代码或身份哈希代码。是对象可以做到这一点,例如通过自动装箱基元值获得的包装器对象。
其次,正如你自己的实验所证明的那样,整体想法是完全错误的。如果提供基元作为参数,则它将自动装入相应包装类的实例中,并返回结果对象的标识哈希代码。对象的标识哈希代码在其生存期内具有该对象的唯一特征,并且与其状态无关。没有两个同时存在的对象具有相同的标识哈希代码。因此,更有趣的是,您获得的不是自动装箱 s 的不同身份哈希代码,而是自动装箱小整数的相同身份哈希码。System.identityHashCode()
double
实际上,这表明 Java 为小整数值维护了一个对象缓存。它在对所涵盖的范围内的值进行自动装箱处理时,以及在处理对这些值的显式调用时使用这些值。因此,在您的示例中,每次自动装入整数 5 时,您都会获得相同的对象,并且您会看到相同的标识哈希代码。如果您使用了足够大的值,则不会看到相同的效果。Integer
Integer.valueOf()
Java 不会对值为 5.0 的 s 执行此类高速缓存。Double
另一方面,也许你只是误解了这个教训。表示相同基元类型和值的不同包装对象不具有相同的标识哈希代码,但它们确实具有相同的(常规)哈希代码,因为对于包装类,这是由它们表示的原始值确定的。因此,将代码的结果与以下结果进行比较:
System.out.println(Double.valueOf(double1).hashCode()); System.out.println(Double.valueOf(double2).hashCode());
添加回答
举报