1.new Integer和Integer.valueOf()的区别
public static void main(String[] args) {
Integer a1 = new Integer(123);
Integer a2 = new Integer(123);
Integer b1 = Integer.valueOf(123);
Integer b2 = Integer.valueOf(123);
System.out.println(a1 == a2);//false
System.out.println(b1 == b2);//true
Integer c1 = new Integer(12345);
Integer c2 = new Integer(12345);
Integer d1 = Integer.valueOf(12345);
Integer d2 = Integer.valueOf(12345);
System.out.println(c1 == c2);//false
System.out.println(d1 == d2);//false
}
由上面例子可以看出,new Integer每次生成的Integer对象都是不同的;当Integer.valueOf(arg); arg转换后的范围在-128~127(范围可以根据下面源码解析得出)之间的数字,生成的两个Integer对象是相同的,而arg不在-128 ~127范围(Integer的整体范围-2147483648 ~2147483647)则会以新对象的方式生成,具体原因可看2.源码解析。
2.Integer.valueOf源码解析
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
上面代码可看出若是输入参数i的范围在IntegerCache缓存池最小值(low)和最大值(high)之间,则将缓存池中的对象返回,若不在缓存池中,则以new Integer产生新的Integer对象。
IntegerCache缓存池源码解析
//定义Integer缓存池全局最小值
static final int low = -128;
//定义Integer缓存池全局最大值
static final int high;
//定义Integer缓存池对象数组
static final Integer cache[];
static {
// 设置初始化的h为127
int h = 127;
// 从jvm启动参数中获取配置的Integer缓存池的high值
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {//若配置的high值存在
try {
// 将配置high值转为int类型
int i = parseInt(integerCacheHighPropValue);
// 将配置high值与127相比,将较大的赋值给i
i = Math.max(i, 127);
// 限制h不能超过MAX_VALUE-128,用于后面限制数组大小,防止缓存池大小超过Integer正数范围
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;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// 至少保留缓存池对象数值范围为-128~127
assert IntegerCache.high >= 127;
}
3.扩展
Integer a = 123;
Integer b = 123;
System.out.println(a == b); // true
编译器会在自动装箱过程调用 valueOf() 方法,因此多个值相同且值在缓存池范围内的 Integer 实例使用自动装箱来创建,那么就会引用相同的对象。
其他基础类型对应对象默认的数值范围:
- boolean values true and false
- all byte values
- short values between -128 and 127
- int values between -128 and 127
- char in the range \u0000 to \u007F
本文详细解析了Java中Integer对象的缓存机制,对比了new Integer与Integer.valueOf的区别,深入源码揭示valueOf方法如何利用IntegerCache实现-128至127范围内整数的复用,以减少内存消耗。

904

被折叠的 条评论
为什么被折叠?



