假设System.identityHashCode(object1)==123和object1是垃圾收集的,那么新创建的object2有没有可能和object1在被垃圾收集之前拥有相同的身份哈希码呢?
System.identityHashCode(object1)==123
object1
object2
inb24sb21#
新创建的object2是否可能具有与object1在被GC之前获得的相同的标识散列代码?是的,它是。身份散列码 * 可能 * 是 * 从 * 对象的地址 * 派生 * 的,当这个方法第一次被对象调用的时候。(或者它 * 可能 * 是以其他方式生成的。这个规范允许使用很多不同的机制。)因此,如果GC收集object1,并且新对象object2被分配在与原始对象相同的地址,并且新对象 * 可能 * 具有与原始对象相同的散列码。此外,如果GC在生成散列码后移动object1,新对象(object2)将位于object1的原始位置。然后,您可能会得到两个具有相同散列码的 * 现有 * 对象。但这两件事都不应该成为问题。散列码不是设计来作为对象的标识符的。(所以不要试图这样使用它们。)我对标识的理解是,在给定的时间点,对象在JVM中是唯一的。身份是唯一的,但身份散列码不是唯一的,正如Object javadoc所说:
Object
hashCode
这远不能保证独一无二。然后道:
当hashCode()第一次被调用时,它所引用的是对象的地址。hashCode()方法的约定声明hashcode值不能改变。标识hashcode被...实际上...作为对象的一部分被记住,这样对象就可以被GC移动。请注意,最新的javadoc已经删除了所有关于身份散列码是如何生成或可能如何生成的内容,这一变化发生在Java12中。
hashCode()
6uxekuva2#
从定义上来说,这是可能的。identityHashCode是一个int。在Java中只有232个不同的整数。您可以轻松地编写一个程序来创建232个以上的对象。
identityHashCode
int
2条答案
按热度按时间inb24sb21#
新创建的object2是否可能具有与object1在被GC之前获得的相同的标识散列代码?
是的,它是。
身份散列码 * 可能 * 是 * 从 * 对象的地址 * 派生 * 的,当这个方法第一次被对象调用的时候。(或者它 * 可能 * 是以其他方式生成的。这个规范允许使用很多不同的机制。)
因此,如果GC收集
object1
,并且新对象object2
被分配在与原始对象相同的地址,并且新对象 * 可能 * 具有与原始对象相同的散列码。此外,如果GC在生成散列码后移动
object1
,新对象(object2
)将位于object1
的原始位置。然后,您可能会得到两个具有相同散列码的 * 现有 * 对象。但这两件事都不应该成为问题。散列码不是设计来作为对象的标识符的。(所以不要试图这样使用它们。)
我对标识的理解是,在给定的时间点,对象在JVM中是唯一的。
身份是唯一的,但身份散列码不是唯一的,正如
Object
javadoc所说:hashCode
方法确实为不同对象返回不同的整数。"*这远不能保证独一无二。
然后道:
当
hashCode()
第一次被调用时,它所引用的是对象的地址。hashCode()
方法的约定声明hashcode值不能改变。标识hashcode被...实际上...作为对象的一部分被记住,这样对象就可以被GC移动。请注意,最新的javadoc已经删除了所有关于身份散列码是如何生成或可能如何生成的内容,这一变化发生在Java12中。
6uxekuva2#
从定义上来说,这是可能的。
identityHashCode
是一个int
。在Java中只有232个不同的整数。您可以轻松地编写一个程序来创建232个以上的对象。