今天,我们来理解一下,我们经常在开发中使用的Integer引用数据类型:
先抛出问题:
Integer i = 127;
Integer c = 127;
System.out.println(i == c);
我们运行的结果是:
true
我们又试着使用下面的代码运行:
Integer i = 128;
Integer c = 128;
System.out.println(i == c);
然而现在的结果出乎我们意料:
false
这是为什么呢,我们使用debug查看原因(我事先翻译了一下)
/**
* 返回一个表示指定的{@code Integer}实例
* {@code int}值。如果一个新的{@code Integer}实例不是
* 必要时,一般应优先使用此方法
* 构造函数{@link #Integer(int)},
* 就像这个方法一样产生明显更好的空间和时间性能缓存频繁请求的值。
* <p>
* 该方法缓存的值总是在-128到127之间,
* 包含,并可能缓存该范围之外的其他值。
* JDK 1.5
*/
public static Integer valueOf(int i) {
//该方法缓存的值总是在-128到127之间
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可以看出他是使用IntegerCache中的静态变量那么我们 来查看一下这个类里面到底是什么为什么是在-128到127之间
/**
* 缓存支持对象标识语义的自动装箱之间的值
* 根据JLS要求-128和127(含)
* <p>
* 缓存在第一次使用时被初始化。缓存的大小由{@code -XX:AutoBoxCacheMax=<size>}选项控制。
* 在虚拟机初始化时,java.lang.Integer.IntegerCache。高属性
* 可以设置和保存在私有系统属性在
* sun.misc。VM类。
*/
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
h = Math.min(i, Integer.MAX_VALUE - (-low) - 1);
} catch (NumberFormatException nfe) {
// 如果无法将属性解析为int,请忽略它。
}
}
high = h;//high=127;
//计算结果[127-(-128)+1]=256;
cache = new Integer[(high - low) + 1];
int j = low;//int j=-128;
for (int k = 0; k < cache.length; k++)
//cache[256]=重新创建了一个对象
cache[k] = new Integer(j++);
// 范围[-128,127]必须是内部的(JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
// 不允许创建对象
private IntegerCache() {
}
}
我们看到注释中写到:缓存在第一次使用时被初始化。缓存的大小由{@code -XX:AutoBoxCacheMax=}选项控制。,既然缓存由**-XX:AutoBoxCacheMax=**来控制,那我们是不是来设置他的缓存大小:那我们就尝试来设置一下他的缓存大小
然后我们在来运行一下我们的代码,结果是:
true
具体的分析内容可以查看上的代码注释