我在JBoss服务器上遇到一个奇怪的问题,其中两个类产生相同的hashCode()
。
Class<?> cl1 = Class.forName("fqn.Class1");
Class<?> cl2 = Class.forName("fqn.Class2");
out.println(cl1.getCanonicalName());
out.println(cl2.getCanonicalName());
out.println(cl1.hashCode());
out.println(cl2.hashCode());
out.println(System.identityHashCode(cl1));
out.println(System.identityHashCode(cl2));
out.println(cl1 == cl2);
out.println(cl1.equals(cl2));
out.println(cl1.getClassLoader().equals(cl2.getClassLoader()));
产地:
fnq.Class1
fnq.Class2
494722
494722
494722
494722
false
false
true
我通常不会关心,但我们正在使用一个框架,该框架使用由类中的哈希码和属性名称组成的密钥来缓存setter。它是一个糟糕的缓存设计,但目前我无法控制(最新的Struts 2.3.24中的OGNL 3.0.6,请参阅source。更新的OGNL解决了这个问题,但是它不会在Struts中使用,直到2.5,目前处于测试阶段。)
这个问题对我来说有点奇怪是
我读到Hotspot中的RNG哈希码生成器(&#34; 0&#34;策略)如果有赛车线程可以产生重复,但是我无法想象类加载会触发这种行为。 / p>
在创建Class
实例时,Hotspot是否使用特殊的哈希码处理?
答案 0 :(得分:5)
java.lang.Class
不会覆盖hashCode
,JVM也不会特别处理它。这只是从java.lang.Object
继承的常规标识hashCode。-XX:hashCode=0
(JDK 6和JDK 7中的默认值)时,使用全局Park-Miller随机数生成器计算标识hashCode。此算法生成周期为2^31-2
的唯一整数,因此除了以下原因外,两个对象几乎不可能具有相同的hashCode。hashCode
方法时生成的。因此,何时以及如何加载类并不重要。如果同时调用hashCode
,则任何两个对象都可能发生此问题。-XX:hashCode=5
(默认为JDK 8)。此选项使用线程本地Xorshift RNG。它不受竞争条件的影响,也比Park-Miller算法快。