qidao123.com技术社区-IT企服评测·应用市场

标题: 口试官:包装类型的缓存机制了解么? [打印本页]

作者: 立山    时间: 2025-4-23 07:29
标题: 口试官:包装类型的缓存机制了解么?
看下面代码
  1. Integer a = 100;
  2. Integer b = 100;
  3. System.out.println(a == b);//true
  4. Integer c = 200;
  5. Integer d = 200;
  6. System.out.println(c == d);//false
复制代码
为什么第一个输出的是true,第二个输出的是false?
Integer a = 100的这种直接赋值操作,是调⽤Integer.valueOf(100)方法,从Integer.valueOf()源码可以看到,返回的是Integer对象,但这里的实现并不是简朴的new Integer,而是先判断 i 这个值是否在IntegerCache范围内,如果在,直接返回IntegerCache中的值,如果不在则new Integer
  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. }
  6. private static class IntegerCache {
  7.     static final int low = -128;
  8.     static final int high;
  9.     static final Integer cache[];
  10.     static {
  11.         // high value may be configured by property
  12.         int h = 127;
  13.         String integerCacheHighPropValue =
  14.             sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
  15.         if (integerCacheHighPropValue != null) {
  16.             try {
  17.                 int i = parseInt(integerCacheHighPropValue);
  18.                 i = Math.max(i, 127);
  19.                 // Maximum array size is Integer.MAX_VALUE
  20.                 h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
  21.             } catch( NumberFormatException nfe) {
  22.                 // If the property cannot be parsed into an int, ignore it.
  23.             }
  24.         }
  25.         high = h;
  26.         cache = new Integer[(high - low) + 1];
  27.         int j = low;
  28.         for(int k = 0; k < cache.length; k++)
  29.             cache[k] = new Integer(j++);
  30.         // range [-128, 127] must be interned (JLS7 5.1.7)
  31.         assert IntegerCache.high >= 127;
  32.     }
  33.     private IntegerCache() {}
  34. }
复制代码
从源码可以看到,默认Integer cache 的下限是-128,上限默认127。当赋值100给Integer时,刚幸亏这个范围内,所以从cache中取对应的Integer并返回,所以a和b返回的是同一个对象,所以  比较是相等的,当赋值200给Integer时,不在cache 的范围内,所以会new Integer并返回,当然  比较的结果是不相等的。
扩展:Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character 创建了数值在 [0,127] 范围的缓存数据,Boolean 直接返回 True or False
  1. System.out.println(Integer.valueOf(-128) == Integer.valueOf(-128));//1.true
  2. System.out.println(Integer.valueOf(127) == Integer.valueOf(127));//2.true
  3. System.out.println(Integer.valueOf(128) == Integer.valueOf(128));//3.false
  4. System.out.println(Integer.parseInt("128") == Integer.valueOf(128));//4.true
复制代码
1、2、3都好明白,缓存范围是 [-128,127],1、2都在范围内,返回的是缓存中的对象,因此输出true,3不在范围内,返回的是新 new 的Integer,因此输出false。
那为什么4输出的是true呢? 128 在缓存范围外,按道理会 new 出一个Integer对象,为什么输出true呢?
注意:利用==运算符时,需要一边是基本数据类型才会自动拆箱,如果双方都是引用数据类型,是不会自动拆箱的。
<blockquote>当基础类型与它们的包装类有如下几种情况时,编译器会自动进行装箱或拆箱:
<ul>赋值操作(装箱或拆箱)
进行加减乘除混淆运算 (拆箱)
进行>,=,




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4