Java数值类型缓存

  首先给大家看一道面试题:

        Integer a=100,b=100,c=200,d=200;
        System.out.println(a==b);
        System.out.println(c==d);

题的大概内容与这个类似,就是比较两个 int 包装类的值

很多小伙伴一看题,想都不想:true true 。。

你有没有想过,要是这么 low 的题,面试官是考你什么呢?

相信看过 jdk 源码的小伙伴一定知道结果不是这样的

小编先公布结果,再给大家解释下原因

第一个输出语句结果是:true

第二个输出语句结果是:false

很多人看到这个结果有点差异,就连我自己刚接触的时候也是比较纳闷的,所以小编的好奇心就带着小编过去点了一下

 /**
     * 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.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */

    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 =
                sun.misc.VM.getSavedProperty("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 j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

这个就是 java8 中的 Integer 类中的一个内部缓存类(其他版本的jdk实现有可能不一样但是效果都是一样的),这个类的作用就是将 -128~127 之间的整型做了一个缓存

这个东西注释里已经写的比较清楚了,缓存在第一次使用时初始化,可以使用 -XX:AutoBoxCacheMax=(SIZE) VM 启动参数 来改变改变之后的缓存区间为 [-128~SIZE]

 

具体的作用,小编也不是很清楚,有可能是经过统计,使用 -128~127 之间范围的整型比较频繁,所以做了个缓存吧(这个只是小编的推测,还望大佬多多指教)

 

 

其实不止是 Integer ,在 Java 中所有的整型都是有缓存的,在 Byte 中也是有的,这个缓存的大小正好也是 Byte 的范围

所以,小伙伴们,以后遇到这样的“坑”果断的跳过,这就是看多看源码的好处,为什么大厂要求源码必看,养成好习惯大厂不是梦!!

 

下面给大家拓展一下:

        Integer i1 = 12;//反编译后同i3一样
        Integer i2 = new Integer(12);//强制 new
        Integer i3 = Integer.valueOf("12");//如果在缓存范围内,直接返回缓存的值;如果大于或者小于缓存范围,才会 new
        int i4 = 12;//基本类型,只会和自己的包装类比较只会比较值(看值一样就是true)
        System.out.printf("i1==i2: %s \n", (i1 == i2));//false
        System.out.printf("i1==i3: %s \n", (i1 == i3));//true
        System.out.printf("i1==i4: %s \n", (i1 == i4));//true
        System.out.printf("i2==i3: %s \n", (i2 == i3));//false
        System.out.printf("i2==i4: %s \n", (i2 == i4));//true
        System.out.printf("i3==i4: %s \n", (i3 == i4));//true

 

posted @ 2019-06-03 22:59  chbyiming  阅读(935)  评论(0编辑  收藏  举报