Java的Object.hashCode()的返回值到底是不是对象内存地址?

关于这个问题,查阅了网上的资料,发现证明过程太繁琐,这里我用了反证法。

java.lang.Object.hashCode()的返回值到底是不是对象内存地址?

hashCode契约

说到这个问题,大家的第一反应一定和我一样——去查Object.hashCode的源码,但翻开源码,看到的却是这样的(Oracle JDK 8):

 1 /**
 2      * Returns a hash code value for the object. This method is
 3      * supported for the benefit of hash tables such as those provided by
 4      * {@link java.util.HashMap}.
 5      * <p>
 6      * The general contract of {@code hashCode} is:
 7      * <ul>
 8      * <li>Whenever it is invoked on the same object more than once during
 9      *     an execution of a Java application, the {@code hashCode} method
10      *     must consistently return the same integer, provided no information
11      *     used in {@code equals} comparisons on the object is modified.
12      *     This integer need not remain consistent from one execution of an
13      *     application to another execution of the same application.
14      * <li>If two objects are equal according to the {@code equals(Object)}
15      *     method, then calling the {@code hashCode} method on each of
16      *     the two objects must produce the same integer result.
17      * <li>It is <em>not</em> required that if two objects are unequal
18      *     according to the {@link java.lang.Object#equals(java.lang.Object)}
19      *     method, then calling the {@code hashCode} method on each of the
20      *     two objects must produce distinct integer results.  However, the
21      *     programmer should be aware that producing distinct integer results
22      *     for unequal objects may improve the performance of hash tables.
23      * </ul>
24      * <p>
25      * As much as is reasonably practical, the hashCode method defined by
26      * class {@code Object} does return distinct integers for distinct
27      * objects. (This is typically implemented by converting the internal
28      * address of the object into an integer, but this implementation
29      * technique is not required by the
30      * Java&trade; programming language.)
31      *
32      * @return  a hash code value for this object.
33      * @see     java.lang.Object#equals(java.lang.Object)
34      * @see     java.lang.System#identityHashCode
35      */
36     public native int hashCode();

Object.hashCode()是一个native方法,看不到源码(Java代码,Oracle的JDK是看不到的,OpenJDK或其他开源JRE是可以找到对应的C/C++代码)。

上面这段注释指出了Object.hashCode()在JRE(Java Runtime Library)中应该遵循的一些契约(contract): 
(PS:所谓契约当然是大家一致达成的,各个JVM厂商都会遵循)

(1)一致性(consistent),在程序的一次执行过程中,对同一个对象必须一致地返回同一个整数。

(2)如果两个对象通过equals(Object)比较,结果相等,那么对这两个对象分别调用hashCode方法应该产生相同的整数结果。(PS:这里equalshashCode说的都是Object类的)

(3)如果两个对象通过java.lang.Object.equals(java.lang.Ojbect)比较,结果不相等,不必保证对这两个对象分别调用hashCode()也返回两个不相同的整数

 因为每个对象的内存地址都是不一样的,如果hashCode()的返回值是对象内存地址,那么两个对象分别调用hashCode()方法将会返回两个截然不同的整数,这与契约三矛盾了,因此java.lang.Object.hashCode()的返回值不是对象内存地址

在这里我觉得hashCode()方法的返回值是对象内存地址通过hash算法计算之后的哈希码值,因此才会出现两个对象分别调用hashCode()返回同一个值。

posted @ 2017-03-19 17:39  杜子龙  阅读(1296)  评论(1编辑  收藏  举报