Java1.5以后,为了进一步解放程序员的双手,Java引用了自动装箱(AutoBoxing)和拆箱(UnBoxing)。

概念:

  • 自动装箱:Java自动将原始数据类型转化为相应的包装类对象,例如,把int转化为Integer。
  • 拆箱:自动装箱的反过程,相应的包装类对象转化为原始数据类型,例如,把Integer转为int。

实现机制:

当发生自动装箱时,编译器自动调用了valueOf()方法,得到相应的包装器对象,当发生拆装时,编译器自动调用了xxxValue()方法(例如IntValue,LongValue等)。

实例:

public class TeatAutoEncap {
    public static void main(String[] args) {

        Byte b1=10;  //自动装箱
        byte b2=b1;  //自动拆箱
        System.out.println(b1.doubleValue());
        System.out.println(b2);

        Short s1=100;  //从长度为256的数组中,取出预先创建好的一个Short对象(此对象代表整数100) 0x7777
        Short s2=100;
        Short s3=300;
        Short s4=300;
        /****************************
         * java预先创建了256个常用的整数包装类型对象
         ****************************/
        System.out.println(s1==s2);
        System.out.println(s1.equals(s2));
        System.out.println(s3==s4);
        System.out.println(s3.equals(s4));
    }
}

运行结果:

10.0
10
true
true
false
true

相信很多人会对运行结果有疑问,下面我就来解释一下:

  • 在Integer里,valueOf是以上这样实现的,为了降低内存占用和垃圾回收的成本,类库里增加了一个cache,保存常用的int包装器对象(-128~127),当数值在这个范围时,就从cache里取出对象,所以i1和i2指同一个内在块,输出就为true。而i3和i4的值大于127,就不会在这个cache里取值,重新new一个对象,因此不是同一个内存块,输出就为false。
  • Integer和Long都是使用了cache机制,所以在-128-127之间,比较都为true,但是Ingeger的cache大小可以通过参数来改变,但是Long却不行。
  • 例如:
public class Main {
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Long g = 3L;
        Long h = 2L;
 
        System.out.println(c==(a+b));//1
        System.out.println(c.equals(a+b));//2
        System.out.println(g==(a+b));//3
        System.out.println(g.equals(a+b));//4
        System.out.println(g.equals(a+h));//5
    }
}

运行结果:
true
true
true
false
true

解释:

  1. a拆箱,b拆箱,相加结果为int,c拆箱,int和int相比较.
  2. a拆箱,b拆箱,相加结果为int,方法equals的参数是Object,所以int又要装箱,引用比较,又因为数据3在cache里,所以为true.
  3. a拆箱,b拆箱,相加结果为int,转化为long型,g拆箱,数值相比较,为true.
  4. a拆箱,b拆箱,相加结果为int,方法equals的参数是Object,所以int又要装箱为Integer,Long和Integer比较,所以为false.
  5. a拆箱,b拆箱,相加结果为long,方法equals的参数是Object,所以要装箱为Long,Long和Long相比较,所以为true。
    从以上测试中,可以得出以下结论:
    当基本数据类型和包装器类型做’'运算时,包装器类型会拆箱为基本数据类型,再做‘’运算。