看代码观察现象:
public class TestInteger {
public static void main(String args[]) {
Integer a =127;
Integer b =127;
System.out.println(a==b);
a=128;
b=128;
System.out.println(a==b);
a=-127;
b=-127;
System.out.println(a==b);
a=-128;
b=-128;
System.out.println(a==b);
a=-129;
b=-129;
System.out.println(a==b);
}
}
结果:
true
false
true
true
false
结果说明 在值域为 [-128,127] 之间,用 == 符号来比较 Integer 的值,是相等的。为啥会有这样的结果呢?因为 Integer 内部特别处理了这之间的数。
观看源码:
/**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch(NumberFormatException nfe) {// If the property cannot be parsed into an int, ignore it.}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
这是 Integer 的静态内部类,在 Integer 类装入内存中时,会执行其内部类中静态代码块进行其初始化工作,做的主要工作就是把 [-128,127] 之间的数包装成 Integer 类并把其对应的引用存入到 cache 数组中,这样在方法区中开辟空间存放这些静态 Integer 变量,同时静态 cache 数组也存放在这里,供线程享用,这也称静态缓存。我们知道在 Java 的对象是引用的,所以当用 Integer 声明初始化变量时,会先判断所赋值的大小是否在 -128 到 127 之间,若在,则利用静态缓存中的空间并且返回对应 cache 数组中对应引用,存放到运行栈中,而不再重新开辟内存。如此,便导致了上面 Integer 比较用 == 比较结果为 true 的情况发生。