隐藏在装箱拆箱中的缓存机制

tech2022-07-10  153

首先让我们先来看一段代码,这段代码的输出和你想的一样吗?

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

最新回复(0)