细节问题2:Integer什么时候会使用常量池里的值什么时候会new一个?

细节问题2:Integer什么时候会使用常量池里的值什么时候会new一个?

package classandobject;

public class Integer_Int {
    public static void main(String[]args){
      // 1)基本类型和包装类型
        int a = 100;//常规量,
        Integer b = 100;//自动装箱,但是100在-128到127之间,使用常量池存放,不用new一个
        System.out.println(a == b);//b拆箱,这里就是比较值的大小了。

        // 2)两个包装类型
        Integer c = 100;//自动装箱,但是100在-128到127之间,没有使用new,默认放在栈里边,是地址引用,100存储在方法区的常量池中
        Integer d = 100;//自动装箱,但是100在-128到127之间,没有使用new,默认放在栈里边,是地址引用,100存储在方法区的常量池中
        System.out.println(c == d);//true,地址引用相同
        System.out.println(c==a);//true 自动拆箱
        Integer c_new = new Integer(100);
        System.out.println(c_new==c);//false,因为地址引用不同
        // 3)常规量
        c = 200;//c = c.valueOf(200),200不在-128到127之间,所以会使用new创建对象
        d = 200;//也就是说这里c,d都使用了new,

        System.out.println(c == d);//使用new创建的对象地址引用不同,false
        System.out.println(c.equals(d));//比较的是值,true

            }
}

在这里插入图片描述

解析
之前我们已经知道了,自动装箱是通过 Integer.valueOf() 完成的,那我们就来看看这个方法的源码吧。

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)//low=-128,high = 127
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);//发现没有,装箱过程可能会用到new
}
//我们来看一下条件是什么:
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;
        int i = parseInt(integerCacheHighPropValue);//
        i = Math.max(i, 127);
        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);//基本都是h = i了。。。
        high = h;//high = i;

        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;
    }
}

valueOf() 方法的实现比较简单,就是先判断值是否在缓存池中,如果在的话就直接返回缓存池的内容。在 Java 8 中,Integer 缓存池的大小默认为 -128~127。编译器会在自动装箱过程调用 valueOf() 方法,因此

多个值相同且值在缓存池范围内(-128~127)的 Integer 实例使用自动装箱来创建,那么就会引用相同的对象。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章