Java的Integer缓存池用法

 更新时间:2025年02月07日 11:01:35   作者:空说  
Java的Integer缓存池主要为了提升性能和节省内存,它缓存了-128到127范围内的Integer对象,因此这些对象在比较时会直接比较引用,而不是值,其他包装类如Byte、Short、Character也有类似的缓存池

Java的Integer缓冲池?

Integer 缓存池主要为了提升性能和节省内存。根据实践发现大部分的数据操作都集中在值比较小的范围,因此缓存这些对象可以减少内存分配和垃圾回收的负担,提升性能。

在-128到 127范围内的 Integer 对象会被缓存和复用。

原理

int 在自动装箱的时候会调用Integer.valueOf,进而用到了 IntegerCache。

@HotSpotIntrinsicCandidate
public static Integer value0f(int i){
    if(i>= IntegerCache.low && i<= IntegerCache.high)  //如果传入的int值在缓存范围内,则直接从缓存中返回Integer对象
        return IntegerCache.cache[i+(-IntegerCache.low)];
    return new Integer(i);                              //否则,创建新的Integer对象
}
private static class IntegerCache{
    static final int low=-128;
    static final int high;
    static final Integer cache[];
    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue = VM.getSavedProperty( key:"java.lang.Integer.IntegerCache.high");
        if(integerCacheHighPropValue != null){
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i,127);
                // Maximum array size is Integer.MAX_VALUE
                h= Math.min(i,Integer.MAX_VALUE-(-low)-1);
            }catch( NumberFormatException nfe){
            //If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;
        
        cache =new Integer[(high-low)+1];
        int i = low;
        for(int k=0;k< cache.length; k++)    //遍历创建-128-127的所有对象
            cache[k]= new Integer(i++);
        assert IntegerCache.high >= 127;
    }
    
    private IntegerCache(){}
}

所以这里还有个面试题:就是为啥 Integer 127 之内的相等,而超过 127 的就不等了?

因为小于等于127的 Integer 对象是从同一个缓存池中获取的,它们指向的是相同的对象实例,所以它们的引用相等

不仅 Integer 有,Long 同样有一个缓存池,不过范围是写死的 -128 到 127,不能通过JVM参数进行调整

@HotSpotIntrinsicCandidate
public static Long value0f(long l){
    final int offset = 128;
    if(l>= -128 &&l<= 127){ // will cache
        return LongCache.cache[(int)l + offsetl];
    }
    return new Long(l);
}

总结

  • Byte,Short,Integer,Long这4种包装类默认创建了数值[-128,127]的相应类型的缓存数据
  • Character 创建了数值在 [0,127]范围的缓存数据
  • Boolean 直接返回 True or False
  • Float 和 Double 没有缓存数据,毕竟是小数,能存的数太多了

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java连接Oracle数据库实例解析

    Java连接Oracle数据库实例解析

    数据库的操作是当前系统开发必不可少的开发部分之一。接下来通过本文给大家介绍Java连接Oracle数据库实例解析,非常不错具有参考借鉴价值,感兴趣的朋友一起学习吧
    2016-06-06
  • 使用hutool工具进行导入导出excel表格

    使用hutool工具进行导入导出excel表格

    如何在后台添加导入导出表格的功能呢,本期的文章将会带领小伙伴们一起实现此功能,文中有详细的代码示例和图文介绍,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-10-10
  • java外部类与内部类的关系详解

    java外部类与内部类的关系详解

    本文详细讲解了java外部类与内部类的关系,用代码演示了外部类调用内部类的方法。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • Java判断是否为闰年的方法示例

    Java判断是否为闰年的方法示例

    这篇文章主要介绍了Java判断是否为闰年的方法示例,本文直接给出示例代码,并讲解了判断原理,需要的朋友可以参考下
    2015-06-06
  • Java mysql详细讲解双数据源配置使用

    Java mysql详细讲解双数据源配置使用

    在开发过程中我们常常会用到两个数据库,一个数据用来实现一些常规的增删改查,另外一个数据库用来实时存数据。进行数据的统计分析。可以读写分离。可以更好的优化和提高效率;或者两个数据存在业务分离的时候也需要多个数据源来实现
    2022-06-06
  • 怎样给Kafka新增分区

    怎样给Kafka新增分区

    这篇文章主要介绍了怎样给Kafka新增分区问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • SpringBoot整合jnotify实现针对指定目录及其(动态)子目录的监听的方法

    SpringBoot整合jnotify实现针对指定目录及其(动态)子目录的监听的方法

    本文介绍了JNotify这一Java库在SpringBoot中的应用,JNotify允许应用程序监听文件系统事件,包括文件夹/文件的创建、删除、修改和重命名,由于JNotify底层调用的关键部分是C语言开发的,所以在使用前需要在系统中加入相应的动态库
    2024-10-10
  • Spring Boot使用FastJson解析JSON数据的方法

    Spring Boot使用FastJson解析JSON数据的方法

    本篇文章主要介绍了Spring Boot使用FastJson解析JSON数据的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • springboot+redis实现订单过期(超时取消)功能的方法详解

    springboot+redis实现订单过期(超时取消)功能的方法详解

    在Spring Boot中使用Redis实现订单过期(超时取消)功能,有多种成熟方案,本文为大家整理了几个详细方法,文中的示例代码讲解详细,大家可以根据需要进行选择
    2025-12-12
  • SpringBoot 中使用 Validation 校验参数的方法详解

    SpringBoot 中使用 Validation 校验参数的方法详解

    Validation 是用于检查程序代码中参数的有效性的框架,作为 Spring 框架中的一个参数校验工具,集成在 spring-context 包中,这篇文章主要介绍了SpringBoot 中使用 Validation 校验参数,需要的朋友可以参考下
    2022-05-05

最新评论