浅析装箱与拆箱操作

什么是装箱和拆箱
简单来说,装箱就是把基本类型用它们相应的引用类型包装起来,使其具有对象的性质。例如,
Integer a = 10;
而拆箱则是将引用类型的对象简化成值类型的数据,例如,
b = new Integer(10);

在java.lang包中,有如下的对应关系:

byte - Byte
char - Character
short - Short
int - Integer
long - Long
float - Float
double  - Double
boolean - Boolean

装箱与拆箱的具体过程
以int和Integer为例看一个简单的例子

public class Text{
     public static void main(String[]args) {
				Integer a = 10;
				int b=new Integer (10);
				System.out.println("a = "+a);
				System.out.println("b = "+b);
				System.out.println(a == b);
     }
}

这个例子的输出结果是:

a = 10
b = 10
true

那么这个例子中装箱与拆箱操作分别是怎么实现的呢?来看看JVM底层都做了些什么:

在Dos命令行中键入javap -c Text指令,可以看到
浅析装箱与拆箱操作_第1张图片
在运行时执行了valueOf()方法和intValue()方法,那这两个方法又是用来干什么的呢,我们可以通过用 source insight 查看 :
浅析装箱与拆箱操作_第2张图片

valueOf()方法具体操作是先定义int型常量a =10,执行 if 判断语句,发现a = 10在int型数据的取值范围内,则在0-256的IntegerCache的范围长度中找到对应的下标并作为一个对象缓存下来,便于后续调用。

对于整型当数值在取值范围之间([-128,127])时,相同元素只会生成一个对象,只有超过范围之后才会每个数值都生成一个新对象。
对于浮点型都是生成新对象。

valueOf() 方法有以下几种不同形式:

valueOf(boolean b): 返回 boolean 参数的字符串表示形式。.

valueOf(char c): 返回 char 参数的字符串表示形式。

valueOf(char[] data): 返回 char 数组参数的字符串表示形式。

valueOf(char[] data, int offset, int count): 返回 char 数组参数的特定子数组的字符串表示形式。

valueOf(double d): 返回 double 参数的字符串表示形式。

valueOf(float f): 返回 float 参数的字符串表示形式。

valueOf(int i): 返回 int 参数的字符串表示形式。

valueOf(long l): 返回 long 参数的字符串表示形式。

valueOf(Object obj): 返回 Object 参数的字符串表示形式。

再来看看intValue()方法:

浅析装箱与拆箱操作_第3张图片
结合我们的语句int b = new Integer(10)可以看到,intValue()方法就是把Integer的值作为一个 int 型常量返回。
同样的,有byteValue(),shortValue(),longValue(),floatValue(),doubleValue()等几种方法。


*一般来说,当一个基础数据类型与封装类进行==、+、-、、/运算时,会先将封装类进行拆箱,再与基础数据类型进行运算。

Integer a = 10;
int b = 20;
int c = 30;
System.out.println(a + b);     //30
System.out.println(c==(a + b));//true

装箱操作的使用场景

一般来说,装箱操作主要用于这两种场合:
1.赋值时使用:
在对Integer类型的变量直接赋值时会发生自动装箱操作,将Integer对象赋值给int时会发生自动拆箱操作。当赋值大于127时,Integer每赋值一次都会产生一个新的Integer对象。
2.调用方法,传递对象参数类型时:
比如我们不能直接在集合中放入基本类型值,因为集合只接收对象类型。我们可以将基本类型的值转换成对象,然后将这些转换的对象放入集合中。


忽略自动装箱带来的可能后果
1.int型初始值为0,Integer型初始值为null,会出现数据异常错误。
2.在循环中使用自动装箱可能会产生多余的对象,造成空间浪费。例如

Integer sum = 0;
for (int i = 0; i <= 100 ; i++){
sum = sum + i;
}

这段程序的运行过程是:sum为Integer类型,sum=sum+i时,首先将sum自动拆箱成int类型跟i相加,然后相加完成后sum又自动装箱成Integer对象,每相加一次,就会产生一个Integer对象。 在上面的循环中会创建100个无用的Integer对象,会降低程序的性能并且加重了垃圾回收的工作量。

你可能感兴趣的:(浅析装箱与拆箱操作)