尝试运行这段代码:
相似的两段代码,得到的结果却完全不相同。
首先要知道在java中==
比较的是对象的引用,从直觉出发,无论是integer1、integer2还是integer3、integer4都是不同的引用,结果都应该是不等的。
造成这个结果的原因是JDK1.5引入的包装类自动装箱时的缓存机制
自动装箱的概念:
Integer a = 10; //自动装箱,相当于下面这句
Integer a = Integer.valueOf(10);
而看看Integer中valueOf(int)
的源码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];//这句就是我们要研究的重点
return new Integer(i);
}
IntegerCache是一个缓存类,它的内部有一个静态的Integer cache[]
数组,在这个类第一次被加载时,会用整数值在-128~127之间的Integer实例对象填充这个数组,如果调用valueOf方法的时候参数值在这个范围内,就会从IntegerCache中的cache数组去取出这样一个共享对象。
这样就能回答一开始的程序integer1、integer2为什么相等了,因为他们都是从cache数组中取出来的同一个引用。
而300这个数是不在-128~127之间的,缓存数组中不存在这样的对象,最终是调用了构造方法创建了两个不同的Integer对象。
拓展:IntegerCache的静态代码块
static {
// 缓存的数据范围可以由用户设置,这里从配置中获取了用户设置的缓存范围
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;
// 这里循环构造Integer对象填充cache数组
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;
}
原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/java%e8%87%aa%e5%8a%a8%e8%a3%85%e7%ae%b1%e7%bc%93%e5%ad%98%e6%9c%ba%e5%88%b6/