一、前言

Java自动装箱和自动拆箱是JDK5.0版本提供的新特性,所以在JDK5.0后的版本中都可以使用,之前的版本则不支持该特性。

理解自动装箱和自动拆箱需要先对java中的8种原始数据类型和相对应的封装类有所了解。

 

二、8种原始数据类型及其对应的封装类



byte       ---> Byte

 short      ---> Short

 int        ---> Integer

 long       ---> Long

 float      ---> Float

 double     ---> Double

 char       ---> Character

 boolean    ---> Boolean



注:原始数据类型的封装类都在java.lang包下,可以直接使用

 

三、什么是自动装箱

自动装箱指的是:可以将一个原始数据类型直接赋值给相应的封装类,其类型转换工作由java编译器自动处理,如:



Byte b = 1;

Short s = 2000;

Integer i = 300000;

Float f = 2.5f;

Double d = 2.555;

Character c = '中'; 

Boolean bln = true;



在没有自动装箱时(JDK5.0前的版本),想要创建一个原始数据类型封装类对象,需要改成下面这种形式(以Integer为例):



//以下三种方式都可创建一个Integer对象

Integer i = new Integer(1);

Integer j = new Integer("1");

Integer k = new Integer.valueOf(1);



注:自动装箱可以简单理解为原始数据类型可以自动装载成封装类

 

四、什么是自动拆箱

自动拆箱指的是:原始数据类型的封装类对象可以当作原始数据类型来处理,其中的转换工作由java编译器自动处理,如:



Integer i = 2000;

Character c = '中'; 

int value = i + c + 100;



在没有自动拆箱前(JDK5.0前的版本),上述操作需要改成下面这种形式:



Integer i = 2000;

Character c = '中';

int value = i.intValue() + c.charValue() + 100;



注:自动拆箱可以简单理解为原始数据类型的封装类可以自动转换成原始数据类型

 

五、自动装箱、自动拆箱带来的好处

在实际开发中,我们经常会操作原始数据类型的封装类,也经常需要对原始数据类型与封装类相互转换或做一些运算,

如果没有自动装箱和自动拆箱,这些操作装会很烦琐。所以自动装箱和自动拆箱带来的好处是很明显的。

 

六、使用自动装箱与自动拆箱需要注意的问题,下面以2个案例来说明(面试中常见)

(1) 阅读下面代码,写出输出结果



Integer i = 100;
Integer j  = 100;
System.out.println(i == j);
System.out.println(i.equals(j));

Integer m = 200;
Integer n = 200;
System.out.println(m == n);
System.out.println(m.equals(n));

int k = 100;
System.out.println(k == j);
System.out.println(j.equals(k));



(2) 阅读下面代码,写出输出结果



Integer i = 100;

Integer j = new Integer(100);

Integer k = Integer.valueOf(100);

System.out.println(i == j);

System.out.println(j == k);



 

(3)下面代码是否有正确?如果正确,输出结果是什么?



Integer i = 100;
long j = 100;
Long k = 100;

System.out.println(i == j);
System.out.println(j == k);



 

案例分析(1) :

输出结果是:



true
true
false
true
true
true



理解这道题的关键点有2个:

 1. "=="比较运算符是引用地址比较,equals()方法是内容比较(注:可通过重写equals()方法自定义比较规则)

 2. 原始数据类型在自动装箱成封装类对象时,如果原始数据类型的值为-128~127(相当于byte值范围),java编译器会判断曾经是否有作过相同的转换,如果有,则把以前装载好的封装类对象的引用地址直接赋给当前对象,所以Integer i = 100,Integer j = 100中,i 跟 j 共享一个Integer对象

 

案例分析(2) :

输出结果是:



false
false



原因:new Integer(100) 与 Integer.valueOf(1)都是重新new出一个对象,所以i,j,k是三个不同的对象

 

案例分析(3)

代码有误,Long k = 100需要改成Long k = (long) k;