浅谈IntegerCache
前言
emm,因为之前笔试中遇到了这个问题,当时写的时候是猜的😭,现在好好捋一下为什么。
IntegerCache
先看一下下面的例子,猜猜三个结果。
public class Main {
public static void main(String[] args){
Integer a = new Integer(5);
Integer b = new Integer(5);
Integer a1 = 127;
Integer b1 = 127;
Integer a2 = 128;
Integer b2 = 128;
System.out.println(a==b);
System.out.println(a1==b1);
System.out.println(a2==b2);
}
}
结果
false
true
false
分析
第一组为false,很好理解,因为a和b都是引用不同的实例对象,自然地址不同。
第二组第三组呢,为什么第二组为true,第三组为false呢。这就要涉及到今天要讲的IntegerCache了。
(往下走👇)
源码解析
// Integer类中含有IntegerCache这样一个内部类
private static class IntegerCache {
// 缓存的最低值
static final int low = -128;
// 缓存的最高值
static final int high;
// 缓存数组
static final Integer cache[];
static {
// high的值是可以通过属性配置的
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
// 如果配置了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 a = 数字的时候,其实有一个自动封装的过程
Integer a = 11;
// 实际运行时为
Integer a = Integer.valueOf(11);
我们可以看到,当i
在IntegerCache的low~high
中的时候,那么会直接返回 缓存数组cache
中的Integer。
public static Integer valueOf(int i) {
// 如果i处于low~high中
if (i >= IntegerCache.low && i <= IntegerCache.high)
// 返回 缓存数组cache 中对应的 Integer
return IntegerCache.cache[i + (-IntegerCache.low)];
// 否则new一个新的Integer实例对象
return new Integer(i);
}
结论
现在我们就知道了,为什么第二组和第三组一个为true,一个为false。
默认的IntegerCache缓存范围为-128~127
第二组的127是在缓存范围内的a1,b1自动封装获取到的都是同一个Integer,所以结果为true。
第三组128不在缓存范围内,两次自动封装分别new是不同的Integer,所以结果为false。