zoukankan      html  css  js  c++  java
  • Java自动装箱拆箱

    一、装箱、拆箱定义


      如果一个int型量被传递到需要一个Integer对象的地方,那么,编译器将在幕后插入一个对Integer构造方法的调用,这就叫做自动装箱。而如果一个Integer对象被放到需要int型量的地方,则编译器将幕后插入一个队intValue方法的调用,这就叫做自动拆箱。

        public static void main(String[] args) {
            // 装箱
            Integer i1 = Integer.valueOf(1);
            // 自动装箱
            Integer i2 = 1;// 默认执行valueOf(1);
            System.out.println(i1 == i2);// true
    
            // 自动拆箱
            int i3 = i1.intValue();
            int i4 = i2.intValue();
            System.out.println(i3 == i4);// true
            
            // 超出Integer的缓存范围,不从私有静态内部类IntegerCache的数组cache中获得,通过new返回新对象
            Integer i5 = 128;
            Integer i6 = -129;
            Integer i5_1 = 128;
            Integer i6_1 = -129;
            System.out.println(i5 == i5_1);// false
            System.out.println(i6 == i6_1);// false
        }

      所以说,对于-127~127之间的值,Integer对象中存在一个IntegerCache的私有静态内部类,这个内部类有一个Integer类型的静态常量数组,在这个内部类中通过静态方法块,初始化了这个静态常量数组。默认这个数组保存[-127,128)之间的Integer对象。源码如下:

     1     private static class IntegerCache {
     2         static final int low = -128;
     3         static final int high;
     4         static final Integer cache[];
     5 
     6         static {
     7             // high value may be configured by property
     8             int h = 127;
     9             String integerCacheHighPropValue =
    10                 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
    11             if (integerCacheHighPropValue != null) {
    12                 try {
    13                     int i = parseInt(integerCacheHighPropValue);
    14                     i = Math.max(i, 127);
    15                     // Maximum array size is Integer.MAX_VALUE
    16                     h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
    17                 } catch( NumberFormatException nfe) {
    18                     // If the property cannot be parsed into an int, ignore it.
    19                 }
    20             }
    21             high = h;
    22 
    23             cache = new Integer[(high - low) + 1];
    24             int j = low;
    25             for(int k = 0; k < cache.length; k++)
    26                 cache[k] = new Integer(j++);
    27 
    28             // range [-128, 127] must be interned (JLS7 5.1.7)
    29             assert IntegerCache.high >= 127;
    30         }
    31 
    32         private IntegerCache() {}
    33     }

      通过下面的源码可以知道,为什么Integer i = 128;与Integer y = 128;,通过==比较的结果为false。如果要赋值的int变量在范围内,则返回数组中的对象给Integer,如果不在,则通过带参构造方法,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     }

    二、其它包装类型


      The Java Language Specification, 3rd Edition 写道:

        为了节省内存,对于下列包装对象的两个实例,当它们的基本值相同时,他们总是==:

    • Boolean :全部缓存
    • Byte :全部缓存
    • Character : <=127缓存
    • Short : (-128,127)缓存
    • Long : (-128,127)缓存
    • Float : (没有缓存)
    • Double : (没有缓存)

    其中Character的缓存源码:

     1   private static class CharacterCache {
     2         private CharacterCache(){}
     3 
     4         static final Character cache[] = new Character[127 + 1];
     5 
     6         static {
     7             for (int i = 0; i < cache.length; i++)
     8                 cache[i] = new Character((char)i);
     9         }
    10     }

    其中Float没有缓存,直接返回源码:

    1   public static Float valueOf(String s) throws NumberFormatException {
    2         return new Float(parseFloat(s));
    3     }

    三、用处


      除了包装类提供了额外的方法外,当使用集合框架时,泛型为Object类型,所以如果声明为List<int> list...,则这样是不行的,必须声明为List<Integer> list...。 

    四、存储的位置


      因为是对象,所以存储在堆中。

     

  • 相关阅读:
    markdown图片设置
    编程变量名
    c++ 子类构造函数初始化及父类构造初始化
    idea中解决Git反复输入代码的问题
    idea中修改git提交代码的用户名
    网络相关
    idea Controller层编译Mapper层报错
    java7与java8的新特性
    修改列名以及其数据类型
    修改数据库表的某个字段默认值
  • 原文地址:https://www.cnblogs.com/zhengbin/p/5651879.html
Copyright © 2011-2022 走看看