java中的装箱和拆箱

装箱和拆箱的概念

        从java SE5之后提供了箱和拆箱的功能,以前要定义一个Interger类型为5的值,必须通过new关键字(Integer i = new Integer(5)),有了装箱的功能后,就可以这样定义了(Integer i = 5),拆箱则是相反的过程。

       装箱:java数据类型由基本类型转为对应的包装类型,使其具有对象的功能.

       拆箱:将包装类型转为基本类型.

     

byte(1个字节) char(2个字节) short(2个字节) int(4个字节) float(4个字节) long(8个字节) double(8个字节) boolean(未定)
Byte Character Short Integer Float Long Double Boolean
装箱和拆箱的原理
        java中的装箱和拆箱

反编译后结果为:

        java中的装箱和拆箱

由此可见,装箱调用的是valueOf()方法,拆箱调用的是intValue(),这其实算是java中的语法糖吧.

就拿Integer包装类来说,这其中有个面试喜欢问的陷阱,我们先来看看valueOf()方法的源码

 java中的装箱和拆箱

从源码中可以看出当数值在-128到127之间时,就会从缓存中取数据.

例子1:

public class Main {
    public static void main(String[] args) {
         
        Integer i1 = 127;
        Integer i2 = 127;
        Integer i3 = 128;
        Integer i4 = 128;
         
        System.out.print(i1==i2);
        System.out.print(i3==i4);
    }
}

输出为:truefalse

例子2: 

public class Main {
    public static void main(String[] args) {
         
        Double i1 = 127.0;
        Double i2 = 127.0;
        Double i3 = 128.0;
        Double i4 = 128.0;
         
        System.out.printl(i1==i2);
        System.out.printl(i3==i4);
    }
}

输出为:falsefalse

为什么是这个结果呢,从Double类的源码可知,其valueOf()方法都是通过new生产的数据,而"=="比较的是对象的地址,所以为false.

特别注意:Byte、Character、Short、Integer、Long这几个类的valueOf()方法实现是类似的。

              Float、Double的valueOf()方法实现是类似的。

例子3: 

public class Main {
    public static void main(String[] args) {
         
        Boolean i1 = false;
        Boolean i2 = false;
        Boolean i3 = true;
        Boolean i4 = true;
         
        System.out.print(i1==i2);
        System.out.print(i3==i4);
    }
}

输出为:truetrue

我们看看Boolean类的源码就一清二楚了,

public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }
public static final Boolean TRUE = new Boolean(true);

    /** 
     * The <code>Boolean</code> object corresponding to the primitive 
     * value <code>false</code>. 
     */
 public static final Boolean FALSE = new Boolean(false);

原来Boolean类的valueOf()方法返回的是2个静态变量,所以上面结果为true。

最后再来看个综合的例子:

java中的装箱和拆箱

看看反编译后的结果:

java中的装箱和拆箱

你答对了没有?