话不多说,直接看题
@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 比较常用,这样可以提高效率