一. 🦁 前言
整型、char类型所对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存处理,其目的是提高效率。
缓存处理的原理为:如果数据在-128~127这个区间,那么在类加载时就已经为该区间的每个数值创建了对象,并将这256个对象存放到一个名为cache的数组中。每当自动装箱过程发生时(或者手动调用valueOf()时),就会先判断数据是否在该区间,如果在则直接获取数组中对应的包装类对象的引用,如果不在该区间,则会通过new调用包装类的构造方法来创建对象。
二. 🦁 源码分析
1. valueOf(int i)
@HotSpotIntrinsicCandidate
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 , IntegerCache.high]范围内时,就直接实例化一个Integer对象并返回;否则返回IntegerCache类里面的cache数组里面的数据。
那么到这里,我们就能根据语义想得到了,Integer自动拆箱的缓存工作是由IntegerCache类完成的,咱们来点击查看一下这个类的工作原理。
2. IntegerCache类
我们查看这个类时,发现这个类是Integer的静态内部类,且定义了一个静态代码块,如下
/**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* jdk.internal.misc.VM class.
*/
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
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;
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() {}
}
这个静态内部类包含了三个变量:low,high,cache[]数组。
- 在静态代码块中,先通过VM.getSavedProperty()来获取high的值,检查"integerCacheHighPropValue"变量是否不为空,如果不为空,它尝试使用parseInt()方法将其解析为整数。如果解析成功,它将"i"的值设置为解析后的整数,并将其与127取最大值。然后它计算"h"变量的最大值,即"i"和Integer.MAX_VALUE减去负的"low"值再减1之间的较小值
如果未设置属性值或无法将其解析为整数,则代码会优雅地忽略该属性,并继续使用默认值 127。
- 实例化cache数组的大小为 256,并且循环赋范围为[-128,127]的值进数组中。最后检查是否缓存全部的值(assert IntegerCache.high >= 127)。
- 最后构造私有的构造方法,以防止外部的类访问到IntegerCache。
三. 🦁 总结
这一期的Java基础复习到这里,咱们下一期见!!!