包装类缓存对象

在 Java 中,包装类(如 Integer、Long、Character 等)为了提高性能和节省内存,对一定范围内的值进行了缓存。这种缓存机制使得在某些情况下,相同的值会返回相同的对象,而不是创建新的对象。

1. 包装类的缓存机制

  • 缓存范围 :
    • Integer:默认缓存 -128 到 127 之间的值。
    • Long:默认缓存 -128 到 127 之间的值。
    • Character:缓存 0 到 127 之间的值。
    • Byte:缓存所有可能的值(-128 到 127)。
    • Short:默认缓存 -128 到 127 之间的值。
    • Boolean:缓存 true 和 false。
  • 缓存实现 :
    • 包装类在内部维护了一个缓存数组(如 IntegerCache),在缓存范围内的值会直接从缓存中返回对象。

2. 示例:Integer 的缓存机制

  • 缓存范围内的值 :
    • 在 -128 到 127 之间的值会返回相同的对象。
  • 缓存范围外的值 :
    • 超出缓存范围的值会创建新的对象。

代码示例:

java 复制代码
public class IntegerCacheExample {
    public static void main(String[] args) {
        Integer a = 127; // 使用缓存
        Integer b = 127; // 使用缓存
        System.out.println(a == b); // true

        Integer c = 128; // 超出缓存范围,创建新对象
        Integer d = 128; // 超出缓存范围,创建新对象
        System.out.println(c == d); // false
    }
}

输出:

复制代码
true
false

3. 修改 Integer 的缓存范围

  • 通过 JVM 参数调整缓存范围 :
    • 可以通过 -XX:AutoBoxCacheMax=<size> 参数调整 Integer 的缓存上限。
  • 示例 :
    • 将缓存范围扩大到 -128 到 200。

运行命令:

复制代码
java -XX:AutoBoxCacheMax=200 IntegerCacheExample

代码示例:

java 复制代码
public class IntegerCacheExample {
    public static void main(String[] args) {
        Integer a = 200; // 使用缓存
        Integer b = 200; // 使用缓存
        System.out.println(a == b); // true
    }
}

输出:

复制代码
true

4. 其他包装类的缓存机制

  • Long 缓存机制 :
    • 默认缓存 -128 到 127 之间的值。

代码示例:

java 复制代码
public class LongCacheExample {
    public static void main(String[] args) {
        Long a = 127L; // 使用缓存
        Long b = 127L; // 使用缓存
        System.out.println(a == b); // true

        Long c = 128L; // 超出缓存范围,创建新对象
        Long d = 128L; // 超出缓存范围,创建新对象
        System.out.println(c == d); // false
    }
}

输出:

复制代码
true
false
  • Character 缓存机制 :
    • 缓存 0 到 127 之间的值。

代码示例:

java 复制代码
public class CharacterCacheExample {
    public static void main(String[] args) {
        Character a = 127; // 使用缓存
        Character b = 127; // 使用缓存
        System.out.println(a == b); // true

        Character c = 128; // 超出缓存范围,创建新对象
        Character d = 128; // 超出缓存范围,创建新对象
        System.out.println(c == d); // false
    }
}

输出:

复制代码
true
false

5. 缓存机制的意义

  • 性能优化 :
    • 缓存机制避免了频繁创建和销毁对象,提高了性能。
  • 节省内存 :
    • 对于常用的小范围值,直接使用缓存对象可以减少内存占用。
  • 注意事项 :
    • 在比较包装类对象时,应使用 equals() 方法而不是 ==,因为 == 比较的是对象的引用,而不是值。

代码示例:

java 复制代码
public class WrapperComparison {
    public static void main(String[] args) {
        Integer a = 128;
        Integer b = 128;

        System.out.println(a == b); // false
        System.out.println(a.equals(b)); // true
    }
}

输出:

复制代码
false
true

6. 自定义包装类的缓存

  • 如果需要实现自定义包装类的缓存机制,可以参考 IntegerCache 的实现方式。
  • 示例 :自定义一个 MyInteger 类,并实现缓存机制。

代码示例:

java 复制代码
public class MyInteger {
    private int value;
    private static final MyInteger[] cache = new MyInteger[256];

    static {
        for (int i = 0; i < cache.length; i++) {
            cache[i] = new MyInteger(i - 128);
        }
    }

    private MyInteger(int value) {
        this.value = value;
    }

    public static MyInteger valueOf(int value) {
        if (value >= -128 && value <= 127) {
            return cache[value + 128];
        }
        return new MyInteger(value);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof MyInteger) {
            return this.value == ((MyInteger) obj).value;
        }
        return false;
    }

    @Override
    public String toString() {
        return Integer.toString(value);
    }
}

public class MyIntegerCacheExample {
    public static void main(String[] args) {
        MyInteger a = MyInteger.valueOf(127); // 使用缓存
        MyInteger b = MyInteger.valueOf(127); // 使用缓存
        System.out.println(a == b); // true

        MyInteger c = MyInteger.valueOf(128); // 超出缓存范围,创建新对象
        MyInteger d = MyInteger.valueOf(128); // 超出缓存范围,创建新对象
        System.out.println(c == d); // false
    }
}

输出:

复制代码
true
false

总结

包装类的缓存机制是 Java 中一种重要的性能优化手段,适用于常用的小范围值。在使用包装类时,应注意以下几点:

  1. 了解缓存范围,避免不必要的对象创建。
  2. 在比较包装类对象时,使用 equals() 方法而不是 ==。
  3. 可以通过 JVM 参数调整 Integer 的缓存范围。
  4. 如果需要,可以参考包装类的缓存机制实现自定义缓存。
相关推荐
海的透彻4 小时前
dockerfile如何快速构建容器(java服务)
java·开发语言
code2cat4 小时前
Java工具篇之Gradle:用任务图组织构建与交付
java·开发语言·单元测试·gradle
后台模板学习5 小时前
大模型 Prompt 工程在电商订单系统中的踩坑记录
java·python·prompt
w_zero_one5 小时前
算法--构造
java·数据结构·算法
SL_staff5 小时前
制造业订单交付崩盘?用四层协同框架重建交付可信度(技术实践)
java·产品·全栈
SL_staff6 小时前
打破风控迭代死循环:用决策编排重构业务与技术协作链路
java·产品·全栈
Mikko77 小时前
Redis 连接数满了服务端有错误信息吗?连接数不增加却命令超时?6.2 实测连接池、超时与大 key 怎么判定
java·spring boot·redis·后端
.Bryce.7 小时前
从零到一开发技术名词大全:从需求分析到 AI Agent 工程
java·网络·人工智能·agent·需求分析·agent评测
SL_staff7 小时前
JVS-APS的7个刚性约束设计:从无限产能幻觉到可执行排产的工程实践
java·spring cloud·全栈
代码山河8 小时前
基本类型转换:自动类型转换与强制类型转换
java·学习·架构·教程·面向对象·项目