关于Java中“1000==1000“为false和“100==100“为true?
今天看到了一个很意思的题,一块让大家看看。
先看一段简单的代码:
Integer a = 1000, b = 1000; System.out.println(a == b);//1 Integer c = 100, d = 100; System.out.println(c == d);//2
输出结果为:
false true
如果两个引用指向同一个对象,用" = = “比较是相等的。 如果两个应用指向不同的对象,用” = = "比较是不相等的,因为他们内容相同,但地址不同。
因此,后边一条语句也应该是false,为什么是true呢?
下边来解释一下:
大家可以看看Integer.java类的缓存机制。
在 Integer 的缓存机制里,存在 [-128,127]的数,当我们直接定义 Integer 值的时候,如果这个值在此范围内,Integer 会自行到它的缓存中去取用,反之才新建 Integer 对象。
所以上边所有的小整数是从内部缓存中取得,它实际上在内部做的是:
Integer i = Integer.valueOf(100);
通过底层代码可以发现:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
如果值的范围在[-128,127]之间,它就是从高速缓存中返回实例。
所以就不难发现:
Integer c = 100, d = 100;
指向同一个对象。
那么结果就返回:
true
然而,精彩的就来了!!!
通过反射API,你就能发现 Integer 神奇的缓存机制!!!
大家试着运行下边的代码,感受一下它的魅力。
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Class cache = Integer.class.getDeclaredClasses()[0];
Field myCache = cache.getDeclaredField("cache");
myCache.setAccessible(true);
Integer[] newCache = (Integer[]) myCache.get(cache);
newCache[132] = newCache[133];
Integer a = 2;
Integer b = a + a;
System.out.printf("%d + %d = %d", a, a, b);
}
我就当你们运行了,下边公布答案:
2 + 2 = 5
你们猜对了吗?
原因嘛,下边为你们解释:
在 Integer 的缓存机制中,
cache[0] = -128, cache[1] = -127, cache[2] = -126, ... cache[128] = 0,
懂了吗???
在上面的实例中通过反射获取到缓存的cache数组之后,将cache[133]的值赋给cache[132],意思就是说将5的值赋给4。
当我们使用 Integer b = a + a = 2 + 2 = 4 赋值b的值的时候,其实b是到缓存机制中取到了cache[132]的值,即4,所以后面才会将b的值识别成5,是不是很神奇啊!!!
