Java开发之道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

细节4 变幻莫测——装箱与拆箱

在进行Java编程时,操作的内容基本上都是对象,但是在使用基本数据类型时,却不能像对象一样使用,操作起来也没有操作对象灵活,因此,在某些时候需要将基本数据类型转换为对象以方便操作,这就需要了解什么是装箱与拆箱。

· 装箱

装箱是指将基本数据类型打包为对应的对象类型,如将基本数据类型int 的值打包为Integer对象类型,以及将基本数据类型byte、short、long、float、double和boolean对应地打包为对象类型Byte、Short、Long、Float、Double和Boolean。

· 拆箱

拆箱是指将对象类型转换为对应的基本数据类型,如将Integer对象类型转换为基本数据类型int,以及将对象类型Byte、Short、Long、Float、Double和Boolean对应地转换为基本数据类型byte、short、long、float、double和boolean。

说明

在Java中装箱与拆箱分为两种情况,即手动装箱与拆箱、自动装箱与拆箱。在JDK 1.5之前,需要进行手动装箱与拆箱,从JDK 1.5开始,新增了自动装箱与拆箱功能。

1.手动装箱与拆箱

手动装箱是指使用对象类型将基本数据类型打包为对象类型。

示例:

    int num = 100;                       // 定义基本数据类型变量num
    Integer number = new Integer (num); // 将基本数据类型变量num的值打包为Integer对象类型

说明

上面的代码首先定义了基本数据类型为int型的变量num,并为其赋值为100,然后创建了一个Integer对象类型的变量number,并用Integer类的构造方法将基本数据类型变量num的值打包为Integer对象类型并赋值给变量number,从而实现了将基本数据类型手动装箱为对象类型的操作。

手动拆箱是指将对象类型转换为对象的基本数据类型,其缺点是不能以面向对象的方式来操作对象。

示例:

    Integer number = new Integer (100); // 将基本数据类型的值100打包为Integer对象类型
    int num = number. intValue ();        // 将对象类型转换为基本数据类型int,并赋值给变量num

说明

上面的代码首先创建了Integer对象类型的变量number,其打包的值为100,然后创建了一个基本数据类型为int的变量num,并调用Integer类的intValue ()方法Integer对象类型变量number的值转换为int型,并赋值给int型的变量num,从而实现了将对象类型手动拆箱为基本数据类型的操作。

2.自动装箱与拆箱

自动装箱是指将基本数据类型的常量或变量值直接赋值给对象类型的变量,JDK API会自动将基本数据类型打包为对象类型,从JDK 1.5开始,Java API新增了自动装箱与拆箱的功能。

示例:

    int num = 100;                       // 定义基本数据类型变量num
    Integer number = num;                // 将基本数据类型变量num的值自动装箱为Integer对象类型

说明

上面的代码首先定义了基本数据类型为int型的变量num,并为其赋值100,然后定义了一个Integer对象类型的变量number,并将基本数据类型变量num直接赋值给Integer对象类型的变量number,从而实现了将基本数据类型自动装箱为对象类型的操作。

自动拆箱是指将对象类型变量直接赋值给基本数据类型,JDK API会自动完成将对象类型转换为基本数据类型的操作,而不必调用对象类型的方法进行转换。

示例:

    Integer number = new Integer (100);        // 将基本数据类型的值100打包为Integer对象类型
    int num = number;                         // 将对象类型直接赋值给基本数据类型,完成自动拆箱

说明

上面的代码首先创建了Integer对象类型的变量number,其打包的值为100,然后定义了一个基本数据类型为int的变量num,并直接将Integer对象类型变量number的值赋值给变量num,从而实现了将对象类型自动拆箱为基本数据类型的操作。

注意

虽然自动装箱与拆箱对使用Java提供了方便,但同时也隐含一些危险,所以,在使用时要特别小心,除非对面向对象的知识已经了解得非常透彻,否则一定不要去使用自动装箱与拆箱操作。

下面通过两个示例来说明自动装箱与拆箱可能带来的危害。

示例:

    Integer num1 = 80;    // 将基本数据类型的值80自动装箱为Integer对象类型
    Integer num2 = 80;    // 将基本数据类型的值80自动装箱为Integer对象类型
    if (num1 == num2) {
      System. out. println ("num1与num2相等");
    } else {
      System. out. println ("num1与num2不相等");
    }

上面代码执行后,程序将输出 "num1与num2相等”这样的信息,这是我们希望的结果。

示例:

    Integer num1 = 150;        // 将基本数据类型的值150自动装箱为Integer对象类型
    Integer num2 = 150;        // 将基本数据类型的值150自动装箱为Integer对象类型
    if (num1 == num2) {
      System. out. println ("num1与num2相等");
    } else {
      System. out. println ("num1与num2不相等");
    }

注意

上面代码执行后,程序将输出 "num1与num2不相等”这样的信息,这并不是我们希望的结果。

对于同样的程序,只是改变了一下两个变量num1与num2的值,就会输出不同的结果,这是由于在进行自动装箱时,对于整数值-128~127范围内的数,可以在内存中进行缓存,当两个变量num1与num2的值都是80时,变量num2使用的是内存中的缓存数据80,所以输出了正确的结果,而当num1与num2的值都是150时,由于自动装箱时,150不能在内存中进行缓存,所以输出了错误的结果。

说明

如果希望本示例输出正确的结果,可以将if 语句的条件表达式(num1 == num2)换成(num1. equals (num2)),这样程序就能输出正确的结果 "num1与num2相等”了。