Java中包装类的缓存机制详细讲解

 更新时间:2025年12月22日 09:42:16   作者:kitirose  
Java中的包装类缓存机制是指在Java 5中引入的一个功能,该功能可以帮助节省内存、提高性能,这篇文章主要介绍了Java中包装类缓存机制的相关资料,文中通过代码介绍地方非常详细,需要的朋友可以参考下

Java中包装类的缓存机制是为了提升性能、减少重复对象创建,其中以Integer的缓存最为典型。下面分三部分详细讲解:

一、Integer的缓存机制(重点)

Integer的缓存机制由IntegerCache内部类实现,核心逻辑是:预先创建并缓存一定范围的Integer对象,当需要使用该范围的整数时,直接返回缓存中的实例,而非新创建对象

1. 缓存范围

默认情况下,缓存范围是 -128 ~ 127(Java规范强制要求)。

  • 这个范围是最常用的整数区间(如年龄、索引等),缓存后可大幅减少对象创建开销。
  • 可以通过JVM参数XX:AutoBoxCacheMax=<size>调整上限(仅对127以上有效,下限-128固定),但不推荐(破坏规范一致性)。

2. 触发场景

缓存仅在自动装箱(基本类型→包装类)或调用Integer.valueOf(int) 时生效,直接new Integer(int)会强制创建新对象(不使用缓存)。

代码示例

public class IntegerCacheDemo {
    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(新对象)

        // 显式调用valueOf(触发缓存)
        Integer e = Integer.valueOf(127);
        Integer f = Integer.valueOf(127);
        System.out.println(e == f); // true

        // new关键字(不触发缓存,强制新建)
        Integer g = new Integer(127);
        Integer h = new Integer(127);
        System.out.println(g == h); // false(不同对象)
    }
}

二、其他基本类型包装类的缓存机制

Integer外,部分包装类也有缓存机制,但范围和实现略有不同,总结如下:

包装类缓存范围说明
Byte-128 ~ 127全部缓存(因Byte取值范围仅为-128~127)
Short-128 ~ 127固定范围,不可调整
Long-128 ~ 127固定范围,不可调整
Character0 ~ 127对应ASCII字符(常用字符)
Booleantruefalse仅缓存两个静态实例(Boolean.TRUE/FALSE
Float无缓存浮点型取值范围太广,缓存无意义
Double无缓存同上

代码示例(其他包装类)

// Byte缓存(全部范围)
Byte b1 = 127;
Byte b2 = 127;
System.out.println(b1 == b2); // true(缓存)

// Character缓存(0~127)
Character c1 = 'a'; // ASCII码97,在缓存范围
Character c2 = 'a';
System.out.println(c1 == c2); // true

Character c3 = '中'; // Unicode码20013,超出缓存
Character c4 = '中';
System.out.println(c3 == c4); // false

// Boolean缓存
Boolean bool1 = true;
Boolean bool2 = true;
System.out.println(bool1 == bool2); // true(同一实例)

三、包装类 vs 基本数据类型:使用场景对比

选择的核心依据是:是否需要“对象特性”或“null值”

1. 优先用基本数据类型的场景

  • 局部变量/方法参数:用于临时计算(如循环计数、数值运算),存储在栈内存,访问速度快,无额外对象开销。
  • 性能敏感场景:如高频次计算、大数据量处理(避免自动装箱/拆箱的性能损耗)。
  • 明确不需要null值:基本类型不能为null,可避免NullPointerException(如年龄、分数等必然有值的场景)。

示例

// 局部变量用基本类型(高效)
int count = 0;
for (int i = 0; i < 1000; i++) {
    count += i; // 基本类型运算效率高
}

2. 必须用包装类的场景

  • 集合框架:集合(如ArrayListHashMap)只能存储对象,不能直接存基本类型(需用包装类)。 示例:List<Integer> list = new ArrayList<>();(不能写List<int>)。
  • 泛型:泛型参数必须是对象类型(如class MyClass<T>T不能是int,只能是Integer)。
  • 需要表示“无值”状态:如数据库查询结果可能为null(用Integernull表示“未查询到”,而int无法表示)。
  • 反射/序列化:反射中方法参数、字段类型需用包装类(如Field.getType()返回包装类类型);序列化时对象才能被传输。
  • 工具类方法参数:如Integer.parseInt(String)Objects.equals()等,需传入包装类或依赖对象方法。

3. 注意事项

  • 自动装箱/拆箱的坑:频繁装箱拆箱会产生额外对象(如List<Integer>中添加int会自动装箱),可能导致性能问题(可考虑Trove等专门的基本类型集合库优化)。
  • ==与equals:包装类用==比较的是对象地址(缓存范围内除外),必须用equals比较值;基本类型直接用==比较值。 示例:Integer a=128; Integer b=128; a.equals(b) → true,但a==b → false

总结

  • 缓存机制是包装类的优化手段,仅Byte/Short/Long/Character/Integer/Boolean有缓存,范围各有不同。
  • 基本类型适合简单计算、局部变量(高效、无null风险);包装类适合集合、泛型、需null值的场景(依赖对象特性)。

实际开发中,根据是否需要“对象特性”或“null值”选择即可,避免过度使用包装类导致性能损耗。

到此这篇关于Java中包装类的缓存机制详细讲解的文章就介绍到这了,更多相关Java包装类缓存机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解SpringMVC中的异常处理机制

    详解SpringMVC中的异常处理机制

    本篇文章将为大家详细介绍一下springmvc的异常处理机制,用到了ControllerAdvice和ExceptionHandler注解,感兴趣的小伙伴可以了解一下
    2022-07-07
  • SpringBoot中@EnableAutoConfiguration和@Configuration的区别

    SpringBoot中@EnableAutoConfiguration和@Configuration的区别

    这篇文章主要介绍了SpringBoot中@EnableAutoConfiguration和@Configuration的区别,@SpringBootApplication相当于@EnableAutoConfiguration,@ComponentScan,@Configuration三者的集合,需要的朋友可以参考下
    2023-08-08
  • java 中RandomAccess接口源码分析

    java 中RandomAccess接口源码分析

    这篇文章主要介绍了java 中RandomAccess接口源码分析的相关资料,需要的朋友可以参考下
    2017-05-05
  • 一文带你解决Java项目开发中java.lang.NoSuchMethodError的问题

    一文带你解决Java项目开发中java.lang.NoSuchMethodError的问题

    在日常 Java 开发中,大家应该都见过报错java.lang.NoSuchMethodError的,本文就带大家拆解一下问题的本质,结合实际案例演示如何排查和解决
    2025-09-09
  • SpringBoot中的Future接口详解

    SpringBoot中的Future接口详解

    这篇文章主要介绍了SpringBoot中的Future接口详解,在异步编程中,我们通常需要处理一些耗时的操作,一种常见的做法是使用 Future 接口来代表一个异步操作的结果,需要的朋友可以参考下
    2023-07-07
  • Java StringBuilder类相关知识总结

    Java StringBuilder类相关知识总结

    这篇文章主要介绍了Java StringBuilder类相关知识总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • SpringBoot整合Sharding-JDBC实现MySQL8读写分离

    SpringBoot整合Sharding-JDBC实现MySQL8读写分离

    本文是一个基于SpringBoot整合Sharding-JDBC实现读写分离的极简教程,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的可以了解一下
    2021-07-07
  • webuploader+springmvc实现图片上传功能

    webuploader+springmvc实现图片上传功能

    这篇文章主要为大家详细介绍了webuploader+springmvc实现图片上传功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09
  • SpringBoot中使用@Scheduled注解创建定时任务的实现

    SpringBoot中使用@Scheduled注解创建定时任务的实现

    这篇文章主要介绍了SpringBoot中使用@Scheduled注解创建定时任务的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Zookeeper原理及在Dubbo中的使用示例详解

    Zookeeper原理及在Dubbo中的使用示例详解

    这篇文章主要为大家介绍了Zookeeper原理及在Dubbo中的使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03

最新评论