自动装箱的面试题踩到的坑

Integer i1 = new Integer(32);
Integer i2 = new Integer(32);
System.out.println(i1 == i2);							//false
System.out.println(i1.equals(i2));						//true

		
Integer i3 = new Integer(132);
Integer i4 = new Integer(132);
System.out.println(i3 == i4);							//false
System.out.println(i3.equals(i4));						//true


Integer i5 = 32;
Integer i6 = 32;
System.out.println(i5 == i6);							//true
System.out.println(i5.equals(i6));						//true


Integer i7 = 132;
Integer i8 = 132;
System.out.println(i7 == i8);							//false
System.out.println(i7.equals(i8));						//true

以前只知道装箱和拆箱在JDK能自动了,没研究过代码,这两天看面试题的时候,踩到了雷,如上第三段代码的i5 == i6的判断还是想当然的填了个false,测试结果发现是true。

不知道原因,查了下源码

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

发现Integer 里存在一个缓存,IntegerCache.low和IntegerCache.high两个静态变量,分别被赋值为-128和127,也就是byte的范围。而在这个缓存内,自动装箱就不会创建新的对象,而是直接从常量池里获取,这也是为什么第三段和第四段代码除了数值不同,没有其他不同,结果却不同的原因。

此外,查了一下其他的自动装箱代码,会发现:Byte、Float、Double没有缓存;Integer、Short、Long的缓存范围都是[-128,127];Character的缓存范围是[0,127]。

你可能感兴趣的:(java基础)