java基础学习(1)-new Integer与Integer.valueOf区别及源码解析

文章目录

  • 1.new Integer和Integer.valueOf()的区别
  • 2.Integer.valueOf源码解析
  • 3.扩展

1.new Integer和Integer.valueOf()的区别

	public static void main(String[] args) {
        Integer a1 = new Integer(123);
        Integer a2 = new Integer(123);
        Integer b1 = Integer.valueOf(123);
        Integer b2 = Integer.valueOf(123);
        System.out.println(a1 == a2);//false
        System.out.println(b1 == b2);//true
        Integer c1 = new Integer(12345);
        Integer c2 = new Integer(12345);
        Integer d1 = Integer.valueOf(12345);
        Integer d2 = Integer.valueOf(12345);
        System.out.println(c1 == c2);//false
        System.out.println(d1 == d2);//false
    }

由上面例子可以看出,new Integer每次生成的Integer对象都是不同的;当Integer.valueOf(arg); arg转换后的范围在-128~127(范围可以根据下面源码解析得出)之间的数字,生成的两个Integer对象是相同的,而arg不在-128 ~127范围(Integer的整体范围-2147483648 ~2147483647)则会以新对象的方式生成,具体原因可看2.源码解析。

2.Integer.valueOf源码解析

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

上面代码可看出若是输入参数i的范围在IntegerCache缓存池最小值(low)和最大值(high)之间,则将缓存池中的对象返回,若不在缓存池中,则以new Integer产生新的Integer对象。

IntegerCache缓存池源码解析

//定义Integer缓存池全局最小值
static final int low = -128;
//定义Integer缓存池全局最大值
static final int high;
//定义Integer缓存池对象数组
static final Integer cache[];

static {
    // 设置初始化的h为127
    int h = 127;
    // 从jvm启动参数中获取配置的Integer缓存池的high值
    String integerCacheHighPropValue =
        sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
    if (integerCacheHighPropValue != null) {//若配置的high值存在
        try {
        	// 将配置high值转为int类型
            int i = parseInt(integerCacheHighPropValue);
            // 将配置high值与127相比,将较大的赋值给i
            i = Math.max(i, 127);
            // 限制h不能超过MAX_VALUE-128,用于后面限制数组大小,防止缓存池大小超过Integer正数范围
            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++);

    // 至少保留缓存池对象数值范围为-128~127
    assert IntegerCache.high >= 127;
}

3.扩展

Integer a = 123;
Integer b = 123;
System.out.println(a == b); // true

编译器会在自动装箱过程调用 valueOf() 方法,因此多个值相同且值在缓存池范围内的 Integer 实例使用自动装箱来创建,那么就会引用相同的对象。

其他基础类型对应对象默认的数值范围:

  • boolean values true and false
  • all byte values
  • short values between -128 and 127
  • int values between -128 and 127
  • char in the range \u0000 to \u007F

你可能感兴趣的:(Java基础知识)