首先让我们先来看一段代码,这段代码的输出和你想的一样吗?
public class Test_1 { public static void main(String[] args) { int a = 1; Integer b = 1; Integer c = Integer.valueOf(1); Integer d = new Integer(1); System.out.println("a == b = " + (a == b)); // true, 自动拆箱,比较的值 System.out.println("a == c = " + (a == c)); // true,自动拆箱,比较的值 System.out.println("a == d = " + (a == d)); // true,自动拆箱,比较的值 System.out.println("b == c = " + (b == c)); // true System.out.println("b == d = " + (b == d)); // false,两个引用的不是同一个对象 System.out.println("c == d = " + (c == d)); // false,两个引用的不是同一个对象 } }把第一段代码中的1都改成128,你觉得输出会变吗?
public class Test_2 { public static void main(String[] args) { int a = 128; Integer b = 128; Integer c = Integer.valueOf(128); Integer d = new Integer(128); System.out.println("a == b = " + (a == b)); // true, 自动拆箱,比较的值 System.out.println("a == c = " + (a == c)); // true,自动拆箱,比较的值 System.out.println("a == d = " + (a == d)); // true,自动拆箱,比较的值 System.out.println("b == c = " + (b == c)); // false,跟上次输出不同 System.out.println("b == d = " + (b == d)); // false,两个引用的不是同一个对象 System.out.println("c == d = " + (c == d)); // false,两个引用的不是同一个对象 } }比较两段代码可以看到,b == c的结果在两段代码中是不一样的。这是为什么呢?
让我们来看下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); }可以看到这里使用了一个缓存区,如果缓存区中有这个对象,就直接返回这个对象,否则就创建一个新的对象。
Integer类中缓存区的大小默认是[-128, 127],所以当我们把代码中的1改成128时,会超出缓存区的范围,因此Integer.valueOf(128)会创建出一个新的对象。
目前在valueOf使用缓存机制的类有:Byte, Short, Integer, Long, Char, Character