哈希码是否返回内存地址?

3

我非常确定在OpenJDK上不会出现这种情况,否则我们会在连续创建对象的identityHashCode()中看到更多的模式。(试一试,创建100个对象,打印它们的哈希码并尝试找到一个模式)。 - Joachim Sauer
我最后一次查看时,如果特定类没有覆盖它,则默认实现是返回从第一次请求哈希码时对象地址派生的整数。当然,对于复制GC,地址可能会更改,因此实现(如果使用地址)必须小心地缓存首先生成的哈希码并始终返回它,而不是重新派生它。哈希码不需要与地址有任何关系,并且对于某些对象(例如字符串),它肯定不基于地址,因为相等的对象必须具有相等的哈希值。 - Hot Licks
这里有一个关于如何的链接:https://dev59.com/mm445IYBdhLWcg3wTIjm - bestsss
@HotLicks,有人真的需要修复这个毫无意义的文档,它只会误导人。 - bestsss
有时候胡言乱语是有意为之的。 - Hot Licks
@HotLicks,也许在其他情况下是这样,但在这种情况下不是。它曾经是这样,但从未更新以反映现实。 - bestsss
4个回答

7
不一定。根据文档(重点是我的):

尽管合理可行,Object类定义的hashCode方法确实会为不同的对象返回不同的整数。(通常通过将对象的内部地址转换为整数来实现,但JavaTM编程语言并不要求使用这种实现技术。)


2
有趣的是 hashcode 是一个整数,很可能计算机的地址空间比可用的整数要大,并且将内部地址转换为整数并不一定是双射关系。 - assylias
“这通常意味着…”的意思是,是否有其他实现方式? - samsamara
1
@user601L,实际上它已经很久很久没有成为(jnit) (void*) address了,实际的实现在对象头中存储了一次性随机数。 - bestsss
但正如文档所述,“如果根据equals(java.lang.Object)方法两个对象不相等,则调用这两个对象上的hashCode方法必须产生不同的整数结果”是不正确的,如果hashcode方法没有被覆盖,对吗? - samsamara
@HotLicks 是的,它说不相等的对象不一定具有不相等的哈希值,我同意这一点。但是如果没有重写 hashcode() 方法,它将为不同的对象返回不同的值,这意味着不相等的对象总是具有不相等的哈希值? - samsamara
显示剩余6条评论

2

您可以通过查看随JDK提供的源代码来进行检查。

我的java.lang.ObjecthashCode显示为本地方法。这是javadoc文档。

/**
 * Returns a hash code value for the object. This method is 
 * supported for the benefit of hashtables such as those provided by 
 * <code>java.util.Hashtable</code>. 
 * <p>
 * The general contract of <code>hashCode</code> is: 
 * <ul>
 * <li>Whenever it is invoked on the same object more than once during 
 *     an execution of a Java application, the <tt>hashCode</tt> method 
 *     must consistently return the same integer, provided no information 
 *     used in <tt>equals</tt> comparisons on the object is modified.
 *     This integer need not remain consistent from one execution of an
 *     application to another execution of the same application. 
 * <li>If two objects are equal according to the <tt>equals(Object)</tt>
 *     method, then calling the <code>hashCode</code> method on each of 
 *     the two objects must produce the same integer result. 
 * <li>It is <em>not</em> required that if two objects are unequal 
 *     according to the {@link java.lang.Object#equals(java.lang.Object)} 
 *     method, then calling the <tt>hashCode</tt> method on each of the 
 *     two objects must produce distinct integer results.  However, the 
 *     programmer should be aware that producing distinct integer results 
 *     for unequal objects may improve the performance of hashtables.
 * </ul>
 * <p>
 * As much as is reasonably practical, the hashCode method defined by 
 * class <tt>Object</tt> does return distinct integers for distinct 
 * objects. (This is typically implemented by converting the internal 
 * address of the object into an integer, but this implementation 
 * technique is not required by the 
 * Java<font size="-2"><sup>TM</sup></font> programming language.)
 *
 * @return  a hash code value for this object.
 * @see     java.lang.Object#equals(java.lang.Object)
 * @see     java.util.Hashtable
 */
public native int hashCode();

2
本地实现在thread.cpp和synchronizer.cpp中:: get_next_hash,http://hg.printk.org/openjdk6-mips/file/tip/hotspot/src/share/vm/runtime/synchronizer.cpp行:270。 - bestsss
无法想象为什么三年后这个被投票否决了。了解如何查看Java源代码是有价值的。你认为Javadoc是从哪里来的? - duffymo

1

正如文档中关于 Object.hashCode() 的说明所述:

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

因此,Java语言对于Object类的哈希码没有要求必须返回对象的内存地址,因此您不应该依赖于此。


1
不,HashCode()函数返回一个整数。如果您没有为对象定义HashCode()函数,Java可能会将对象的内存地址转码为整数并返回该值。

2
它可以使用内存地址,但不一定必须使用。 - Robin
感谢您的纠正,已更新。 - Chris Dargis
@Robin,自从以前开始它就没有返回地址了。 - bestsss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接