String a = new String("test");
String b = new String("test");
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode(b));
System.out.println(a.hashCode());
System.out.println(b.hashCode());
打印结果
1836019240
325040804
3556498
3556498
这是为什么呢,我们知道目前a和b是两个不同的String实例,他们在内存中存放的地址肯定是不相同的,System.identityHashCode方法是java根据对象在内存中的地址算出来的一个数值,不同的地址算出来的结果是不一样的。因此这里打印出的结果不一样。
System.identityHashCode的代码描述:
/**
* Returns the same hash code for the given object as
* would be returned by the default method hashCode(),
* whether or not the given object's class overrides
* hashCode().
* The hash code for the null reference is zero.
*
* @param x object for which the hashCode is to be calculated
* @return the hashCode
* @since JDK1.1
*/
public static native int identityHashCode(Object x);
doc上如是说:返回给定对象的哈希码,该代码与默认的方法 hashCode() 返回的代码一样,无论给定对象的类是否重写 hashCode()。
但是为什么后两个相同呢?这是因为,String类中已经重新写了hashCode()方法,也就是说,String类中hashcode(),已经不是根据对象在内存中的地址计算出来的。具体代码:
/** Cache the hash code for the string */
private int hash; // Default to 0
/**
* Returns a hash code for this string. The hash code for a
* {@code String} object is computed as
* <blockquote><pre>
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
* </pre></blockquote>
* using {@code int} arithmetic, where {@code s[i]} is the
* <i>i</i>th character of the string, {@code n} is the length of
* the string, and {@code ^} indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* @return a hash code value for this object.
*/
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
他是根据String里面存储的内容算出来的,doc里面已经给出来了详细的算法。就是说只要String里面存储的内容一样,调用hashCode()出来的结果就是一样的,大家也可以在自己电脑是试下,和上文输出的地址是一样的。