Integer缓存

作者: 在简书已被 | 来源:发表于2018-03-05 14:48 被阅读4次

之前在看一些java基础的面试题中,出现了一个Integer 自动封装及解封的相关问题。写如下代码:

public class MainClass {
    public static void main(String[] args)
    {
        Integer int1 = Integer.valueOf(128);
        Integer int2 = Integer.valueOf(128);
        Integer int3 = Integer.valueOf(23);
        Integer int4 = Integer.valueOf(23);
        Integer int5 = int1;
        System.out.println(int1 == int2);
        System.out.println(int1 == 128);
        System.out.println(int3 == int4);
        System.out.println(int3 == 23);
    }
}

得出结果:
false
true
true
true

在没看过源码的情况下会觉得比较奇怪。翻阅Integer源码会发现,Integer有一个IntegerCache内部类,默认会对 -128 到 127 之间的数进行缓存。另外我们还可以在JVM参数中设置 -XX:AutoBoxCacheMax=<size> 来设置缓存的范围,size的范围需要在128至 Integer.MAX_VALUE - (-low) -1。这样缓存的数是-128至size和(Integer.MAX_VALUE - (-low) -1)中较小的一个。

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() {}
}

Integer.valueOf(int i),方法实现如下:

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

我们在通过 Integer.valueOf() 方法来获取一个Integer时,如果在我们的缓存区域内,就会直接从缓存中的对象获取。于是有System.out.println(int3 == int4) 输出为true,而System.out.println(int1 == int2)为false。
对开篇是代码进行调试,在进程结束前打上断点:


捕获.PNG

我们可以看到,int1和int2 值相同,但对应的并不是同一个地址@502及@503,因为Integer是对象类型,而不是基本类型,对其进行的 == 操作是判断这两个对象是不是指向同一个对象,因此返回为false。而int3和int4则是指向了同一个对象@504,对他们进行
== 操作返回为true。

至于自动解封的情况,应该是确切的需要接受基本类型的时候才会出现,我们的int5=int1操作中,我们的左值是一个Integer对象类型,而不是一个基础类型,所以直接将int5指向了int1,为同一个对象。

至于为什么要设计这样的缓存机制,尚未深究,后续如果有时间,研究一下JSLJVMS后看能否找到答案。

相关文章

  • Integer缓存机制

    这是Integer中的缓存机制 默认缓存-128~127 Integer integer = 128;我们进...

  • java知识整理-包装类型

    Integer的缓存 Integer内部实现了一个缓存,会缓存-128~127之间的数字。Integer在赋值的时...

  • Java基础-数据类型缓存解析

    基本类型缓存解析 Integer缓存解析: 1、使用自动装箱(Integer i = 1)方式创建Integer对...

  • 深入分析Integer底层原理

    本文将介绍Java中Integer的相关知识,分析Integer缓存的原理和作用。 Integer缓存 在Inte...

  • JDK 源码解析 —— Integer

    说到Java中的Integer包装类,大家或多或少的都听说过Integer缓存,下面我们先从Integer缓存相关...

  • 优秀博客集锦(一)

    理解Java Integer的缓存策略Java中Integer和其他包装类具有缓存机制,会缓存常用的一部分数字。 ...

  • Java装箱类缓存分析

    Integer Integer内部有一个IntegerCache类,这个类用来缓存int型数值,默认缓存的范围是-...

  • Integer缓存

    之前在看一些java基础的面试题中,出现了一个Integer 自动封装及解封的相关问题。写如下代码: 得出结果:f...

  • Integer缓存

    new Integer(123) 与 Integer.valueOf(123) 的区别 观察下面的代码,我们可以看...

  • 9.int 和 Integer 有什么区别,Integer的值缓

    问题:int 和 Integer 有什么区别,Integer的值缓存范围? 一、int 和 Integer 的基本...

网友评论

    本文标题:Integer缓存

    本文链接:https://www.haomeiwen.com/subject/mowcfftx.html