new Integer(123) 与 Integer.valueOf(123) 的区别在于:

    • new Integer(123) 每次都会新建一个对象;
    • Integer.valueOf(123) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。
      1. Integer x = new Integer(123);
      2. Integer y = new Integer(123);
      3. System.out.println(x == y); // false
      4. Integer z = Integer.valueOf(123);
      5. Integer k = Integer.valueOf(123);
      6. System.out.println(z == k); // true
      valueOf() 方法的实现比较简单,就是先判断值是否在缓存池中,如果在的话就直接返回缓存池的内容。
      1. public static Integer valueOf(int i) {
      2. if (i >= IntegerCache.low && i <= IntegerCache.high)
      3. return IntegerCache.cache[i + (-IntegerCache.low)];
      4. return new Integer(i);
      5. }
      在 Java 8 中,Integer 缓存池的大小默认为 -128~127。 ```java 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;

    1. cache = new Integer[(high - low) + 1];
    2. int j = low;
    3. for(int k = 0; k < cache.length; k++)
    4. cache[k] = new Integer(j++);
    5. // range [-128, 127] must be interned (JLS7 5.1.7)
    6. assert IntegerCache.high >= 127;

    }

    编译器会在自动装箱过程调用 valueOf() 方法,因此多个值相同且值在缓存池范围内的 Integer 实例使用自动装箱来创建,那么就会引用相同的对象。
    ```java
    Integer m = 123;
    Integer n = 123;
    System.out.println(m == n); // true
    

    在使用这些基本类型对应的包装类型时,如果该数值范围在缓冲池范围内,就可以直接使用缓冲池中的对象。

    在 jdk 1.8 所有的数值类缓冲池中,Integer 的缓冲池 IntegerCache 很特殊,这个缓冲池的下界是 - 128,上界默认是 127,但是这个上界是可调的,在启动 jvm 的时候,通过 -XX:AutoBoxCacheMax= 来指定这个缓冲池的大小,该选项在 JVM 初始化的时候会设定一个名为 java.lang.IntegerCache.high 系统属性,然后 IntegerCache 初始化的时候就会读取该系统属性来决定上界。