反编译前后对比
源代码:
//直接赋值
Integer m1 = 128;
Integer m2 = 128;
System.out.println(m1 == m2);//false
System.out.println(m1.equals(m2));//true
//显式调用构造器
Integer m3 = new Integer(20);
Integer m4 = new Integer(20);
System.out.println(m3 == m4);
反编译后代码:
//调用Integer.valueOf
Integer m1 = Integer.valueOf(128);
Integer m2 = Integer.valueOf(128);
System.out.println(m1 == m2);
System.out.println(m1.equals(m2));
//调用构造器
Integer m3 = new Integer(20);
Integer m4 = new Integer(20);
System.out.println(m3 == m4);
可以看出
- Integer m1 = 128;实际上是调用了Integer.valueOf(int)这个方法
- Integer m3 = new Integer(20);调用的是构造器
Integer类中的valueOf()方法
- 返回一个表示指定的int值的Integer实例
- 如果不需要新的Integer实例,该方法通常应该优先使用构造函数Integer(int)
- 因为通过缓存经常请求的值,这种方法很可能产生更好的空间和时间性能
- 此方法将始终缓存范围为-128到127的值,并可能缓存此范围之外的其他值。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
//如果在缓存里面,则直接从缓存里面取值
return IntegerCache.cache[i + (-IntegerCache.low)];
//如果缓存里面没有,则在堆内存里重新分配空间
//此时即使相同的两个int值分配的内存空间也是各自独享的
//所以存放的内存地址也是不同的
return new Integer(i);
}
Integer(int)构造函数
构造一个新分配的Integer对象,该对象表示指定的int值。
public Integer(int value) {
this.value = value;
}
Integer类中的缓存类IntegerCache
private static class IntegerCache {
//缓存数组最小值
static final int low = -128;
//缓存数组最大值(可以修改)
static final int high;
//缓存数组
static final Integer cache[];
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);
// 数组最大大小为 Integer.MAX_VALUE
//Integer.MAX_VALUE = 2^31 - 1
//Integer.MAX_VALUE - (-low) -1 <=> 数组除去负整数和0 可以存放的正整数
//此处限制了最大值的范围 [127, 2^31 - 1]
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数组大小为 最大值个数 + 最小值个数 + 0占一个位置
cache = new Integer[(high - low) + 1];
int j = low;
//将整数区间[low, hight]内的整数放入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;
}
private IntegerCache() {}
}