先以问题抛出
Integer a = 12,b=12;
Integer c = 132,d=132;
System.out.println(a==b);
System.out.println(c==d);
相信你一定毫不犹豫的说出 true false
但这道题是有条件的,不一定哦!!!在启动的时候-Djava.lang.Integer.IntegerCache.high
参数指定一下就可以改变这个值,我可以把-128 ~ 整数范围-128-1
范围的数字存进去。所以可能两个值都为true
,不要去背这些东西,要去理解!!!!
源码
让我们一起看看底层实现细节
private static class IntegerCache {
static final int low = -128; // 最小的值
static final int high;
static final Integer cache[]; // 缓存的数组
static { // 默认缓存了 -128~127
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); // 这个参数可以通过-Djava.lang.Integer.IntegerCache.high设置
if (integerCacheHighPropValue != null) { // 不等于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) { // throw error
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1]; // eg:-3 -2 -1 0 1 2 3 因为这个加一
int j = low;
for(int k = 0; k < cache.length; k++) // 为什么这里没有写死,因为high的值可以在程序启动的时候指定
cache[k] = new Integer(j++); // 把值缓存进去
// range [-128, 127] must be interned (JLS7 5.1.7) // 表示整数范围在[-128, 127]之间的值必须被内部化(interned)。内部化是指对于这个范围内的整数值,JVM会保留它们的唯一实例,以节省内存和提高性能。这是根据Java语言规范第7版(JLS7 5.1.7)中的规定来确保这个范围内的整数在使用时始终是相同的对象引用。通过使用内部化,可以避免创建重复的整数对象,提高整数比较的效率。
assert IntegerCache.high >= 127; // 用于验证当前整数缓存的高值是否满足这个要求,如果不满足,则会抛出断言错误。
}
private IntegerCache() {} //私有的构造方法,是为了防止在类外部创建 IntegerCache 的实例。通过将构造方法设置为私有,可确保其他类无法直接实例化 IntegerCache,只能通过类内部的静态初始化块来创建实例。
}
你会发现全局只有valueOf
调用了
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
例子:
全部流程是会先自动装箱,调用valueOf
方法,看看这个值是否在cache
缓存范围,不在就会new
Integer c = 132,d=132;
System.out.println(a==b);
那自动拆箱调用什么呢!
Integer a = 10;
int b = a; // 自动拆箱,将Integer对象a转换为int类型的基本类型值
在上述示例中,将 Integer 对象 a 赋给基本类型变量 b,这里发生了自动拆箱操作。编译器会自动调用 Integer 对象的 intValue() 方法,将其转换为基本类型 int。
// 自动拆箱和自动装箱使得基本类型和对应的包装类之间的转换更加方便,
// 可以在需要基本类型的地方使用包装类对象,而不必手动进行类型转换。