装箱和拆箱是什么?
目录
装箱(Boxing)和拆箱(Unboxing)是将基本数据类型和对应的包装类之间进行转换的过程。
Integer i = 10; //装箱 int n = i; //拆箱
自动装箱主要发生在两种情况,一种是赋值时,另一种是在方法调用的时候。
赋值时
这是最常见的一种情况,在 Java 1.5 以前我们需要手动地进行转换才行,而现在所有的转换都是由编译器来完成。
//before autoboxing Integer iObject = Integer.valueOf(3); Int iPrimitive = iObject.intValue() //after java5 Integer iObject = 3; //autobxing - primitive to wrapper conversion int iPrimitive = iObject; //unboxing - object to primitive conversion
方法调用时
当我们在方法调用时,我们可以传入原始数据值或者对象,同样编译器会帮我们进行转换。
public static Integer show(Integer iParam){ System.out.println("autoboxing example - method invocation i: " + iParam); return iParam; } //autoboxing and unboxing in method invocation show(3); //autoboxing int result = show(3); //unboxing because return type of method is Integer
show 方法接受 Integer 对象作为参数,当调用show(3)
时,会将 int 值转换成对应的 Integer 对象,这就是所谓的自动装箱,show 方法返回 Integer 对象,而int result = show(3);
中 result 为 int 类型,所以这时候发生自动拆箱操作,将 show 方法的返回的 Integer 对象转换成 int 值。
自动装箱的弊端
自动装箱有一个问题,那就是在一个循环中进行自动装箱操作的情况,如下面的例子就会创建多余的对象,影响程序的性能。
Integer sum = 0; for(int i=1000; i<5000; i++){ sum+=i; }
上面的代码sum+=i
可以看成sum = sum + i
,但是+
这个操作符不适用于 Integer 对象,首先 sum 进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成 Integer 对象。其内部变化如下:
int result = sum.intValue() + i; Integer sum = new Integer(result);
由于我们这里声明的 sum 为 Integer 类型,在上面的循环中会创建将近 4000 个无用的 Integer 对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题。