四、8 种基本类型的包装类和常量池

  • Java 基本类型的包装类的大部分都实现了常量池技术, 即Byte,Short,Integer,Long,Character,Boolean; 这 5 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据, 但是超出此范围仍然会去创建新的对象。
  • 两种浮点数类型的包装类 Float , Double 并没有实现常量池技术

valueOf() 方法的实现比较简单,就是先判断值是否在缓存池中,如果在的话就直接返回缓存池的内容。

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. }

在 Java 8 中,Integer 缓存池的大小默认为 -128~127。

  1. static final int low = -128;
  2. static final int high;
  3. static final Integer cache[];
  4. static {
  5. // high value may be configured by property
  6. int h = 127;
  7. String integerCacheHighPropValue =
  8. sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
  9. if (integerCacheHighPropValue != null) {
  10. try {
  11. int i = parseInt(integerCacheHighPropValue);
  12. i = Math.max(i, 127);
  13. // Maximum array size is Integer.MAX_VALUE
  14. h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
  15. } catch( NumberFormatException nfe) {
  16. // If the property cannot be parsed into an int, ignore it.
  17. }
  18. }
  19. high = h;
  20. cache = new Integer[(high - low) + 1];
  21. int j = low;
  22. for(int k = 0; k < cache.length; k++)
  23. cache[k] = new Integer(j++);
  24. // range [-128, 127] must be interned (JLS7 5.1.7)
  25. assert IntegerCache.high >= 127;
  26. }
  • 示例1:
  1. Integer i1=40;
  2. //Java 在编译的时候会直接将代码封装成 Integer i1=Integer.valueOf(40);从而使用常量池中的对象。
  3. Integer i2 = new Integer(40);
  4. //创建新的对象。
  5. System.out.println(i1==i2);//输出false
  • 示例2:Integer有自动拆装箱功能
  1. Integer i1 = 40;
  2. Integer i2 = 40;
  3. Integer i3 = 0;
  4. Integer i4 = new Integer(40);
  5. Integer i5 = new Integer(40);
  6. Integer i6 = new Integer(0);
  7. System.out.println("i1=i2 " + (i1 == i2)); //输出 i1=i2 true
  8. System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); //输出 i1=i2+i3 true
  9. //i2+i3得到40,比较的是数值
  10. System.out.println("i1=i4 " + (i1 == i4)); //输出 i1=i4 false
  11. System.out.println("i4=i5 " + (i4 == i5)); //输出 i4=i5 false
  12. //i5+i6得到40,比较的是数值
  13. System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); //输出 i4=i5+i6 true
  14. System.out.println("40=i5+i6 " + (40 == i5 + i6)); //输出 40=i5+i6 true