`

Integer源码浅析IntegerCache

 
阅读更多
一、引例,看如下代码
		int a = 100, b = 100;
		System.out.println(a == b); // true,缓存了
		Integer c = 1000, d = 1000;
		System.out.println(c == d); // false,没有缓存,要new
		Integer e = -128, f = -128;
		System.out.println(e == f); // true,缓存了
		Integer g = -129, h = -129;
		System.out.println(g == h); // false,没有缓存,要new


二、究竟哪个范围的整型数被缓存而不需要new了呢?先了解一下什么是“自动装箱池”,再围观IntegerCache源码就清楚。

1、看API里面的注释
    /**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage. During VM initialization the
     * getAndRemoveCacheProperties method may be used to get and remove any system
     * properites that configure the cache size. At this time, the size of the
     * cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>.
     */
getAndRemoveCacheProperties方法,用于获取或移除JDK对Integer设置的缓存属性,同时也是调整jvm:AutoBoxCacheMax选项,调整“自动装箱池”的大小
  // value of java.lang.Integer.IntegerCache.high property (obtained during VM init)
    private static String integerCacheHighPropValue; 

    static void getAndRemoveCacheProperties() {
        if (!sun.misc.VM.isBooted()) {
            Properties props = System.getProperties();
            integerCacheHighPropValue =
                (String)props.remove("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null)
                System.setProperties(props);  // remove from system props
        }
    }


2、IntegerCache源码
    // IntegerCache,一个内部类,注意它的属性都是定义为static final
    private static class IntegerCache {
        static final int high; //缓存上界,暂为null
        static final Integer cache[]; //缓存的整型数组
        
        // 块,为什么定义为块
        static {
            final int low = -128; // 缓存下界,不可变了。只有上界可以改变

            // high value may be configured by property
            // h值,可以通过设置jdk的AutoBoxCacheMax参数调整(以下有解释),自动缓存区间设置为[-128,N]。注意区间的下界是固定
            int h = 127;
            
            if (integerCacheHighPropValue != null) {
                // Use Long.decode here to avoid invoking methods that
                // require Integer's autoboxing cache to be initialized
                // 通过解码integerCacheHighPropValue,而得到一个候选的上界值
                int i = Long.decode(integerCacheHighPropValue).intValue();
                // 取较大的作为上界,但又不能大于Integer的边界MAX_VALUE
                i = Math.max(i, 127);     
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - -low);
            }
            high = h; //上界确定
            // 就可以创建缓存块,注意缓存数组大小
            cache = new Integer[(high - low) + 1]; //
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++); // -128到high值逐一分配到缓存数组
        }

        private IntegerCache() {}
    }



看API里面的注释
    /**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage. During VM initialization the
     * getAndRemoveCacheProperties method may be used to get and remove any system
     * properites that configure the cache size. At this time, the size of the
     * cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>.
     */
getAndRemoveCacheProperties方法,用于获取或移除JDK对Integer设置的缓存属性,同时也是调整jvm:AutoBoxCacheMax选项,调整“自动装箱池”的大小
  // value of java.lang.Integer.IntegerCache.high property (obtained during VM init)
    private static String integerCacheHighPropValue; 

    static void getAndRemoveCacheProperties() {
        if (!sun.misc.VM.isBooted()) {
            Properties props = System.getProperties();
            integerCacheHighPropValue =
                (String)props.remove("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null)
                System.setProperties(props);  // remove from system props
        }
    }


-------------------以下为补充内容------------------

最近在看Long类,顺便贴个LongCache来比较,相对Integer简单很多,就像ByteCache一样。
 private static class LongCache {
	private LongCache(){}
        // 可见下界和上界就固定了,-128到127
	static final Long cache[] = new Long[-(-128) + 127 + 1];

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

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

分享到:
评论

相关推荐

    Integer IntegerCache源码阅读

    在源码中,`IntegerCache` 类起着关键作用。 `IntegerCache` 是一个内部私有静态类,它维护了一个缓存数组,用于存储-128到127之间的 `Integer` 对象。这个范围的选择是因为这些数值在Java虚拟机(JVM)中会被自动...

    Java 9中如何对IntegerCache进行修改详解

    在Java 9中,Integer类内部包含了一个名为IntegerCache的静态内部类,它是一个私有的缓存,用于存储-128到127之间的Integer对象。这个缓存机制的存在是为了优化性能,因为在实际应用中,这个范围内的整数对象被频繁...

    nodemcumaster_nodemcu_nodemcu-integer_源码

    nodemcu_integer_master_20200312-1329_nodemcu-master_nodemcusmartconfig_nodemcumaster_nodemcu_nodemcu-integer_源码.rar

    Java Integer.ValueOf()的一些了解

    从源码中我们可以看到,IntegerCache是一个静态内部类,它在类加载的时候就会创建并保存从-128到127的整数值的缓存对象,并将他们的引用保存在cache数组中。 现在,让我们来分析一下Integer.ValueOf()方法的使用...

    mybatis返回Integer

    在使用MyBatis进行数据操作时,我们经常会遇到关于返回值类型的困扰,特别是涉及到基本类型int和对象类型Integer之间的转换。标题"mybatis返回Integer"指的是在MyBatis的映射文件或者Mapper接口中,使用Integer作为...

    Transform Coding with Integer-to-Integer Transforms.pdf

    ### Transform Coding with Integer-to-Integer Transforms #### 概述 《Transform Coding with Integer-to-Integer Transforms》一文由Vivek K Goyal撰写,发表于2000年3月的IEEE Transactions on Information ...

    Clock_Integer 指令库应用例程.rar

    《Clock_Integer 指令库应用详解》 在嵌入式系统开发中,精确的时钟管理是至关重要的。Clock_Integer 指令库提供了一种高效、灵活的方式来处理与时间相关的任务,尤其是在实时操作系统(RTOS)或者微控制器(MCU)...

    扫雷QQ版VB源码.rar

    VB编写的仿Windows扫雷游戏,和系统自带的界面相似,扫雷QQ版VB源码,有什么更好的想法请联系QQ:149550122。Dim bomb_number As Integer '地雷数  Dim flag(63) As Integer '地雷数组 flag=1为右地雷 flag=0为没有...

    HugeInteger大整数计数器作业

    HugeInteger Class) Create a class HugeInteger that uses a 40-element array of digits to store integers as large as 40 digits each. Provide member functions input, output, add and subtract. For ...

    Java源码解析Integer方法解读

    在Java编程语言中,Integer类是int类型的一个包装类,提供了许多方便的静态方法和实例方法来处理整型数据。本文将重点解析Integer类中的一些关键方法,包括toString、toUnsignedString以及highestOneBit。 首先,...

    convert string to integer

    了解了不同语言中字符串转整数的基本方法后,我们可以结合源码和工具来优化或扩展这个功能,比如添加自定义的校验逻辑、处理异常、支持多种进制等。对于开发者来说,熟悉并掌握这些基本操作是至关重要的,因为它们在...

    javainteger源码-Free-Code-Camp:和尚访问群岛的土地。总共有N个岛,编号从1到N。一些岛对通过在水上运行的双向桥相互连

    1. Java Integer类的源码分析:包括Integer对象的创建、自动装箱拆箱、比较操作以及IntegerCache的实现等。 2. 图论基础:介绍图的概念,节点和边,以及如何用数组或链表表示图。 3. 遍历算法:如深度优先搜索(DFS...

    易语言DeviceIoControl取硬盘序列号源码

    .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, ...

    bigdecimal转integer.docx

    在 Java 编程中,`BigDecimal` 和 `Integer` 是两个不同类型的数值表示。`BigDecimal` 用于处理精确的浮点数运算,适合财务或金融计算,因为它可以避免浮点数计算中的精度问题。而 `Integer` 是 Java 中的整数类型,...

    jdk源码(完整版)

    - **java**: 这个包下包含了许多Java语言的基本类,如`Object`、`String`、`Integer`等,以及I/O流、集合框架、网络编程等模块。 - **launcher**: Java应用程序启动器,负责加载JVM并执行主类。 - **sun**: 这个...

    HugeInteger.java

    HugeInteger.java

    Integer类的使用方法

    ### Integer类的使用方法详解 在Java编程语言中,`Integer`类是一个非常重要的封装类,它用于将基本数据类型`int`封装成对象。这不仅增强了数据的灵活性,还提供了许多实用的方法来处理整数相关的操作。下面,我们...

    基于C语言的TurboPFor-Integer-Compression设计源码,实现最快整数压缩算法

    该项目是针对整数压缩的TurboPFor-Integer-Compression算法设计源码,采用C语言实现,包含103个文件,其中C源文件44个,头文件38个,Markdown文件2个,C++源文件2个,Java源文件2个,项目文件2个,过滤文件2个,Git...

    RAR密码探测源码

    用于RAR密码暴力破解的源码-仅供参考 function ExtractArchive(ArcName: PChar; Mode: Integer):boolean; var hArcData: THandle; RHCode, PFCode: Integer; CmtBuf: array[0..Pred(16384)] of Char; HeaderData...

    创建一个IntegerSet(集合类).zip

    本文将深入探讨如何在C++中创建一个名为`IntegerSet`的集合类,以及在这个过程中涉及的关键知识点。 首先,集合类通常用于存储和操作一组特定类型的元素,比如整数。在C++中,我们可以通过定义一个类来实现这个概念...

Global site tag (gtag.js) - Google Analytics