for(int i =0; i <150; i++){Integer a = i;Integer b = i;System.out.println(i +" "+(a == b));}
输出结果:
126true127true.........128false129false
可以看到:从 128 开始 a 和 b 就不再相等
自动装箱
解析这行代码 Integer a = 1
变量 a 为 Integer 类型,而 1 为 int 类型,且 Integer 和 int 之间并无继承关系,按照 Java 的一般处理方法,这行代码应该报错
因为自动装箱机制的存在,在为 Integer 类型的变量赋 int 类型值时,Java 会自动将 int 类型转换为 Integer 类型
赋值变量的时候会执行这行代码:Integer a = Integer.valueOf(1);
valueOf() 方法返回一个 Integer 类型值,并将其赋值给变量 a,这就是 int 的自动装箱
每次循环时,Integer a = i 和 Integer b = i 都会触发自动装箱,而自动装箱会将 int 转换 Integer 类型值并返回
Java 中两个 new 出来的对象因为时不同的实例,无论如何 == 都会返回 fasle,例如:new Integer(1) == new Integer(1);
那么例子 中Integer a = i 和 Integer b = i 自动装箱产生的变量 a 和 b 就不应该时同一个对象了,那么 == 的结果应该时 false
128 以上为 false 容易理解,但为何 (-128)0 到 127 时返回 true 了呢?== 返回 true 的唯一情况是比较的两个对象为同一个对象,那不妨把例子中 a 和 b 的内存地址都打印出来看看
推测:"从 0 到 127 不同时候自动装箱得到的是同一个对象 " 就只能有一种解释:自动装箱并不一定 new 出新的对象
自动装箱涉及到的方法是 Integer.valueOf(),其源码如下:
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/publicstaticIntegervalueOf(int i){if(i >=IntegerCache.low && i <=IntegerCache.high)returnIntegerCache.cache[i +(-IntegerCache.low)];returnnewInteger(i);}
注释里就直接说明了-128 到 127 之间的值都是直接从缓存中取出的,看看是怎么实现的:
如果 int 型参数 i 在 IntegerCache.low 和 IntegerCache.high 范围内,则直接由
IntegerCache 返回,否则 new 一个新的对象返回
IntegerCache.low 就是 -128,IntegerCache.high 就是 127
privatestaticclassIntegerCache{staticfinalint low =-128;staticfinalint high;staticfinalInteger cache[];static{// high value may be configured by propertyint 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 =newInteger[(high - low)+1];int j = low;for(int k =0; k < cache.length; k++)
cache[k]=newInteger(j++);// range [-128, 127] must be interned (JLS7 5.1.7)assertIntegerCache.high >=127;}privateIntegerCache(){}}