话不多说,直接看题
@Test
public void inspectInteger(){
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
Integer i5 = 300;
Integer i6 = 300;
Integer i7 = 1000;
Integer i8 = 1000;
System.out.println(i1==i2); //true
System.out.println(i3==i4); //false
System.out.println(i5==i6); //false
System.out.println(i7==i8); //false
}
默认理解 :
JAVA 用对象创建,默认是引用内存地址,所以 == 判断地址,正常不应该为:true
通过多次对比,我们发现只有值为100时候,不符合我们的逻辑,其它的都为:false
所以:到底是我们对==理解有误,还是值为:100的时候搞鬼了。通常我们有疑惑就得去验证。
直接看Integer 源码 ,
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;
//从这里可以看到,能够Vm配置参数,设置最大值
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); //对比,外部配置值,是否超出了int范围
} 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++);
// 范围 [-128,127] 必须被拘禁
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
源码中有个内部类 IntegerCache 从名字上就可以判断: 整型缓存
可以看到使用了一个Integer[] 数组方式进行缓存 ,而且可以使用VM外部设置: 最大属性值
默认范围 -128 ~ 127 所以 : 也就是说 在这个范围内的 == 都可以为true
把整数常量int 赋值 给 整数对象 Integer 类型,实际上调用了Integer.valueOf方法,通过源码也可以看到
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high) //在范围内的,直接从cache获取
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i); //否则,则new
}
好处:
为什么要这么设计,一个东西诞生不会无缘无故,目前看到说法都是 -128 ~127 比较常用,这样可以提高效率