简述一下这个现象,Integer自动装箱,当数值在-128到127之间,两个Integer值相同时,判断两者==时,返回真,但超过这个范围,则返回假,如下图所示
输出结果如下 :
为什么1的差距会出现这种结果呢?
想要解释这一问题,首先我们需要知道关于Java对于基本数据类型与包装类的转换
编译器可以自动完成基本类型到包装类之间的互相转换,又称拆箱和装箱,对应的方法分别是ValueOf(),和xxxValue的方法
显然,上述代码中,Integer与int的转换是自动的,出现这种问题,一定与装箱的valueOf有很大的关系,看下源码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
粗浅的看一眼,可以发现,他传入数据后,会进行判断,如果在某个范围内,则返回一个数组(具体这个到底是啥一会说),否则就会new一个Integer
那么这个范围将决定这个数字到底会在数组中,还是会new一个
所以我们去看看这个IntegerCache
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer[] cache;
static Integer[] archivedCache;
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
h = Math.max(parseInt(integerCacheHighPropValue), 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
// Load IntegerCache.archivedCache from archive, if possible
CDS.initializeFromArchive(IntegerCache.class);
int size = (high - low) + 1;
// Use the archived cache if it exists and is large enough
if (archivedCache == null || size > archivedCache.length) {
Integer[] c = new Integer[size];
int j = low;
for(int i = 0; i < c.length; i++) {
c[i] = new Integer(j++);
}
archivedCache = c;
}
cache = archivedCache;
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
首先,我们我们一眼就看到了常量low,规定了会不会入那个数组的门槛,在静态代码块中,我们也看到了上限high,其他的就不需要了,我们返回之前的valueOf看,在-128到127,我们会在同一个数组中寻找对应下标,找到你,而一旦超出这个范围,就new了
数组和new Integer都是复杂数据类型,复杂数据类型==比较的肯定是地址,同一个数组,指向的地址都是同一个地址,而new则不同,它不管内容是否相等,都会去堆中新找一块空间去存储,所以-128到127会返回真,而一旦大于127,则返回假