包装类的缓存

45 阅读2分钟

整型、char类型 的包装类,在自动装箱时候,对于-128 ~ 127 之间的数字会进行缓存处理,其目的就是提升性能、减少内存开销而设计的一个优化策略。

核心概念

Java为某些包装类维护了一个静态的,不可变的缓存数组。当你尝试创建这个缓存范围内的对象时,Java不会每次都创建一个新的对象,而是直接返回缓存中已存在的对象的引用;

哪些包装类有缓存?缓存范围是多少

包装类缓存范围备注
Byte-128 ~ 127覆盖所有byte可能的值
Short-128 ~ 127
Integer-128 ~ 127最常用
Long-128 ~ 127
Character0 ~ 127对应的ASCII码
BooleanTRUE、 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);
}

总结:

  1. 自动装箱调用的是valueOf(),而不是new Integer()方法;

  2. 自动拆箱调用的是xxxValue()

  3. 包装类在自动装箱时,为了提高效率,对于-128 ~ 127进行缓存处理,超过范围后,对象之间不可使用==进行比较,而使用equals进行比较