问题:
public class Test1 {
public static void main(String[] args) {
Integer t1 = 127;
Integer t2 = 127;
System.out.println(t1 == t2); // 输出true
Integer t3 = 128;
Integer t4 = 128;
System.out.println(t3 == t4); // 输出false
}
}
反编译该class文件
javap -c Test1
可以看到 Integer t1 = 127 或者 Integer t3 = 128 调用的是java.lang.Integer.valueOf(int i)
即自动装箱
查看源码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可以看到如果i的值在IntegerCache.low 和 IntegerCache.high之间则返回IntegerCache.cache数组的值
IntegerCache是Integer的静态内部类,代码如下:
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;
}
可以看到IntegerCache.low = -128是确定的
IntegerCache.high 是通过integerCacheHighPropValue 和 127的最大值确定的(如果我们输入-Djava.lang.Integer.IntegerCache.high=size的话,即integerCacheHighPropValue != null 否则 IntegerCache.high=127)。当然这个值不能超过Integer.MAX_VALUE - (-low) -1的值。
并且由于这个是static代码块,所以IntegerCache.cache[]在类加载时,实例化low~high之间的Integer实例。
所以,t1和t2是同一Integer实例,t3和t4是不同Integer实例
即 t1 == t2 ,t3 != t4 。
如果-Djava.lang.Integer.IntegerCache.high=255;
输出:
都为 true。
打断点可以看到:IntegerCache.high = 255
参考
https://stackoverflow.com/questions/15052216/how-large-is-the-integer-cache
https://www.cnblogs.com/wang-yaz/p/8516151.html