整型、char类型 的包装类,在自动装箱时候,对于-128 ~ 127 之间的数字会进行缓存处理,其目的就是提升性能、减少内存开销而设计的一个优化策略。
核心概念
Java为某些包装类维护了一个静态的,不可变的缓存数组。当你尝试创建这个缓存范围内的对象时,Java不会每次都创建一个新的对象,而是直接返回缓存中已存在的对象的引用;
哪些包装类有缓存?缓存范围是多少
| 包装类 | 缓存范围 | 备注 |
|---|---|---|
| Byte | -128 ~ 127 | 覆盖所有byte可能的值 |
| Short | -128 ~ 127 | |
| Integer | -128 ~ 127 | 最常用 |
| Long | -128 ~ 127 | |
| Character | 0 ~ 127 | 对应的ASCII码 |
| Boolean | TRUE、 FALSE | 只有两个值都缓存了 |
| Float、Double | 无缓存 | 浮点数没有缓存机制 |
验证包装类的缓存机制
缓存机制最直接的方法就是使用 ==(比较引用地址)进行操作
public class Test {
public static void main(String[] args) {
Integer j = 127;
Integer i = 127;
System.out.println(i == j); // true
Integer a = 130;
Integer b = 130;
System.out.println(a == b); // false 超出范围,是先建的对象
System.out.println(a.equals(b)); // true, equals比较的是值
// 其他类
Long l1 = 127L;
Long l2 = 127L;
System.out.println(l1 == l2); // true
Long l3 = 128L;
Long l4 = 128L;
System.out.println(l3 == l4); // false
}
}
这是Integer的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(),而不是new Integer()方法;
-
自动拆箱调用的是xxxValue()
-
包装类在自动装箱时,为了提高效率,对于-128 ~ 127进行缓存处理,超过范围后,对象之间不可使用==进行比较,而使用equals进行比较