关于我之前的问题,为什么 == 与 Integer.valueOf(String) 的比较对于 127 和 128 给出不同的结果?,我们知道
Integer
class
有一个缓存,用于存储 -128
和 之间的值127
。
只是想知道,为什么在-128和127之间?
Integer.valueOf()文档指出它是“缓存经常请求的值”。但是,经常要求
-128
和 127
之间的值是真实的吗?我认为“经常要求的值”非常主观。
这背后有什么可能的原因吗?
[...]并可能缓存此范围之外的其他值。”
如何实现这一目标?
更大范围的整数
可以被缓存,但至少那些在-128到127之间的必须被缓存,因为它是由Java语言规范强制要求的(强调我的):
如果装箱的值 p 是 true、false、一个字节或 \u0000 到 \u007f 范围内的字符,或者-128 到 127(含)之间的 int 或短数字,则让 r1 和r2 是 p 的任意两次装箱转换的结果。 r1 == r2 的情况总是如此。
该要求的基本原理在同一段中进行了解释:
理想情况下,对给定的原始值 p 进行装箱,总是会产生相同的引用。实际上,使用现有的实现技术这可能不可行。上述规则是务实的妥协。上面的最后一个子句要求始终将某些公共值装箱到无法区分的对象中。 [...]
这确保了在大多数常见情况下,该行为将是所需的行为,而不会造成不当的性能损失,尤其是在小型设备上。例如,内存限制较少的实现可能会缓存所有 char 和 Short 值,以及 -32K 到 +32K 范围内的 int 和 long 值。
您可以使用
-XX:AutoBoxCacheMax
JVM 选项,该选项并未真正记录在
可用热点 JVM 选项列表中。然而,它在
Integer
类中第 590 行周围的注释中提到了:
缓存的大小可以通过 -XX:AutoBoxCacheMax=<size>
选项控制。请注意,这是特定于实现的,可能在其他 JVM 上可用,也可能不可用。
-128 到 127 是默认大小。但 javadoc 还表示,整数缓存的大小
-XX:AutoBoxCacheMax=<size>
选项控制。请注意,它仅设置高值,低值始终为-128。该功能在1.6中引入。 至于为什么是-128到127——这是字节值范围,很自然地将它用于非常小的缓存。
缓存小整数的原因(如果这就是您所要求的)是,许多算法在计算中使用小整数,因此避免这些值的对象创建开销往往是值得的。
换句话说,我认为你问题的答案是“它并不像你想象的那么主观,但确切的界限很大程度上是凭经验决定的……实验证据表明它足够好.”
可以通过系统属性配置可以缓存的最大高整数值,即
java.lang.Integer.IntegerCache.high
-XX:AutoBoxCacheMax
) 。缓存是使用数组实现的。
private static class IntegerCache {
static final int high;
static final Integer cache[];
static {
final int low = -128;
// high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
当您遇到 Integer 类并且始终位于 -128 到 127 范围内时,最好将 Integer 对象转换为 int 值,如下所示。