在 Java 中,执行
int i = 327; // arbitrary int >127
int hashcode1 = System.identityHashCode(i);
int hashcode2 = System.identityHashCode(i);
产生两个不同的值 (
hashcode1 != hashcode2
),如果 i
大于 127。为什么会发生这种情况?
本节包含有关哈希码的实现和使用的信息。随意跳过它。
在Java中,对象的hashcode可以通过调用任何实例化对象的
Object#hashCode()
获得。根据 docs,方法 System#identityHashCode(Object)
返回与直接在作为参数传递的对象上调用 #hashCode()
相同的方法。根据定义,如果(但不仅限于)对象相同(取决于实现,语义相等就足够),则此哈希码必须相等,这意味着相同的对象返回相同的哈希码。
根据this thread/answer,在初始生成之后,哈希码与对象一起存储在堆中的某个地方。
不像
#hashCode()
,System#identityHashCode(Object)
也可以接受基元(例如int
或double
)作为输入参数。我不知道哈希码是否也可以与原语一起存储在 RAM 中,但我猜不会。
奇怪的是,当将
int
变量传递给 #identityHashCode(...)
时,低于并包括 127
的值会产生一个常量哈希码。但是,对于更大的值,重复执行所述方法总是会返回不同的哈希码(至少在我的机器上是这样;))。此外,这适用于任何 double
值(我没有广泛测试 double 或 float)。
像任何其他对象一样,像
Integer
这样的包装类对象似乎不受影响。
注释:
ObjectHolder
类只是为了更容易测试的样板。
public class PrimitiveHashcodes
{
public static void main(String[] args)
{
// creating arbitrary non-null object
Object object = new JPanel(new GridBagLayout(), false);
ObjectHolder objectHolder = new ObjectHolder(object, 127, 128, 'B', 3.14d, new Integer(128));
objectHolder.test();
objectHolder.test();
objectHolder.test();
objectHolder.test();
}
}
class ObjectHolder
{
Object obj;
int intSmall;
int intBig;
char character;
double db;
Integer wrapped;
public ObjectHolder(Object obj, int iSmall, int iBig, char character, double db, Integer wrapped)
{
this.obj = obj;
this.intSmall = iSmall;
this.intBig = iBig;
this.character = character;
this.db = db;
this.wrapped = wrapped;
System.out.println(" Object | IntSmall | IntBig | char | double | wrapped");
System.out.println("---------|----------|----------|----------|----------|---------");
}
public void test()
{
System.out.printf("%08x | %08x | %08x | %08x | %08x | %08x%n", System.identityHashCode(obj),
System.identityHashCode(this.intSmall), System.identityHashCode(this.intBig),
System.identityHashCode(this.character), System.identityHashCode(this.db),
System.identityHashCode(wrapped));
}
}
对象 | 小号 | IntBig | 炭 | 双 | 包裹 |
---|---|---|---|---|---|
34a245ab | 7cc355be | 6e8cf4c6 | 12edcd21 | 34c45dca | 52cc8049 |
34a245ab | 7cc355be | 0133314b | 12edcd21 | 0b1bc7ed | 52cc8049 |
34a245ab | 7cc355be | 7cd84586 | 12edcd21 | 030dae81 | 52cc8049 |
34a245ab | 7cc355be | 1b2c6ec2 | 12edcd21 | 4edde6e5 | 52cc8049 |
- | - | - | - | - | - |
常量 | 常量 | 任意 | 常量 | 任意 | 常量 |
如何解释这种现象?首先如何计算原语的哈希码?