背景
面试题, 相关问题的考察.
题目大概是, 包装类型Integer == 比较的时候 : -127 ~ 128 是否相等.
其他是否相等?
原理
== 比较的是地址. 如果是不同的对象, 那么就不相等.
实践
下面是几个简单实践.
全部新建对象
解释: 新建对象后, 地址不同, 所以都是false
不新建对象
暂时的理解: -127 ~ 128 比较的对象的缓存
一些思考
时间多, 一些灵感
为什么设计这个缓存
HotSpot 团队研究, 90% 以上的整型使用落在 -128~127范围内(2000年代初期数据).
缓存范围 -128~127共 256 个对象 ≈ 4KB 内存(每个 Integer对象约16B)
为什么不多缓存一点
扩大到 -256~255则需 512 对象 ≈ 8KB,收益递减
冷知识: 上限值可以调整
部分源码如下:
java
// IntegerCache 源码片段(OpenJDK 17)
private static class IntegerCache {
static final int low = -128; // 硬编码下限
static final int high;
static {
high = java.lang.Integer.getInteger(
"java.lang.Integer.IntegerCache.high", 127);
// 上限可通过VM参数调整
}
}
为什么下限值不能自定义呢?
防止滥用:若允许下限调至 -1,000,000,可能导致缓存占用数百MB内存
其实其他包装类型也有缓存
缓存范围如下:
类 | 缓存范围 | 可调性 |
---|---|---|
Integer | -128~127 | 仅上限可调 |
Long | -128~127 | 完全不可调 |
Short | -128~127 | 完全不可调 |
Character | 0~127(ASCII范围) | 完全不可调 |
这个居然也是API?
Integer b = new Integer(100); // ⚠️ 已弃用API
9版本被弃用了: 神奇!
java
/**
* @deprecated
* It is rarely appropriate to use this constructor.
* Use {@link #valueOf(int)} to take advantage of caching.
*/
@Deprecated(since="9")
public Integer(int value) {
this.value = value;
}
设计思想
这种设计体现了 Java "80/20法则" 的工程哲学------用最小成本解决大多数问题。