Object.hashCode()与System.identityHashCode()区别

前言

今天无意中阅读SpringBoot的源码,发下了System.identityHashCode()的使用,不了解其作用,所以查阅资料学习,特记录下来。

hashCode 与 identityHashCode

Object.hashCode()和System.identityHashCode()的实现,原理是一致的,底层都是使用同一套算法得到具体的hash值。但是呢,Object中的hashCode()可以被子类重写,例如String,Integer等都重写了hashCode()函数。这样就会出现计算的hashCode值和System.identityHashCode()不一样。

public static void main(String[] args) {

String str1 = new String("123");
String str2 = new String("123");
Object obj = new Object();

System.out.println(System.identityHashCode(str1));
System.out.println(System.identityHashCode(str2));
System.out.println(System.identityHashCode(obj));

System.out.println("----------------------compare---------------------");

System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
System.out.println(obj.hashCode());

}

运行结果:

"C:\Program Files\Java\jdk1.8.0_65\bin\java"......
1830908236
277630005
1288354730
----------------------compare----------------------
48690
48690
1288354730

Process finished with exit code 0

使用场景

可用于判断某个对象是否已经被处理过了,具体参考SpringBoot中ConfigurationClassPostProcessor类的实现:

public class ConfigurationClassPostProcessor implements 
BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

private final Set<Integer> registriesPostProcessed = new HashSet<Integer>();

......................省略部分代码...............................

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 根据对象所在内存地址生成唯一标识
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
// 标记该对象已被处理
this.registriesPostProcessed.add(registryId);

// 处理该对象registry
processConfigBeanDefinitions(registry);
}

......................省略部分代码...............................

}