Integer的缓存机制

Integer的自动装箱和自动拆箱

装箱:基本类型 --> 包装类/引用类型
Integer i1=100; 在编译后,class文件中自动加上了valueOf方法
拆箱:包装类/引用类型 --> 基本类型
int i2 = i1; 在编译后,class文件中自动加上了intValue方法
注意:自动装箱和自动拆箱只发生在编译阶段。
在这里插入图片描述

Integer.valueOf方法

public static Integer valueOf(int i) {
    //判断是否在Integer内部的缓存数组中,如果存在则直接返回缓存数组中的对象
    //IntegerCache是Integer的内部类
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        //根据索引获取缓存中的Integer
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

IntegerCache类

private static class IntegerCache {
    static final int low = -128;  //缓存池中最小值,-128
    static final int high;        //缓存中最大值,默认为127
    static final Integer cache[];

    static {
        // 最大值默认为127 
        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;
		//开辟大小为(high - low) + 1的Integer数组
        cache = new Integer[(high - low) + 1];
        int j = low;
        //IntegerCache类初始化的时候就对内部的cache数组进行初始化缓存池
        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() {}
}

注:数组赋值的另外写法
int ii[];
ii = new int[5];
System.out.println(Arrays.toString(ii));  //[0, 0, 0, 0, 0]

代码示例

Integer i1 = 100;
Integer i2 = 100;
System.out.println(i1==i2); //true  因为取出来的都是缓存池中的Integer对象,所以对象地址相同
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println(i3==i4);  //false   超出了缓存池,新创建对象
System.out.println(i3.equals(i4));  //true  比较值,相等

结论

创建Integer的时候,以下两种方法:
方法1:Integer n = new Integer(100); //总是创建新的对象
方法2:Integer n = Integer.valueOf(100); //静态工厂方法,尽可能地返回缓存的实例以节省内存
所以,为了节省内存,Integer.valueOf()对于较小的数,始终返回相同的实例,因此,有时候使用 == 比较“恰好”为true,但我们绝不能因为Java标准库的Integer内部有缓存优化就用 == 比较,必须用equals()方法比较两个Integer

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值