关于java自动拆装箱

                            返回主页

在javaSE5.0之前没有自动拆装箱功能的语法糖,如果需要将int、long、double、float、boolean等当做对象使用必须手动打包,如下代码所示

int data1 = 10;
int data2 = 20;

Integer wrapper1 = new Integer(data1);
Integer wrapper2 = new Integer(data2);

System.out.println(data1 / 3);
System.out.println(wrapper1.doubleValue() / 3);
System.out.println(wrapper1.compareTo(wrapper2));

代码中的Integer以及Long、Double、Float、Boolean等类是所谓的打包器(wrapper)

这些类主要的目的就是提供对象实例作为“壳”,将基本类型打包在对象之中,这样就可以操作这个对象,就像是将基本类型当做对象进行操作。

每次都这么做的确有些繁琐,因此在5.0之后jdk提供了自动装箱(Autoboxing)的功能。改写上述代码如下

Integer data1 = 10;//自动装箱
Integer data2 = 20;
int data3 = data1;//自动拆箱,此处将Integer直接赋值给int类型
System.out.println(data1.doubleValue() / 3);
System.out.println(data2.compareTo(data1));
System.out.println(data3);

简单多了对吧。

有了自动拆装箱,我们就可以利用这个语法糖直接将基本类型转换成引用类型进行操作,也可以自动拆箱之后进行计算。

自动拆装箱的原理

自动拆装箱实际上是编译程序语法糖,在编译期间编译器会根据所写的代码决定是否进行装箱或者拆箱的动作。

例如:

Integer num = 100;

上述代码会在编译期间展开为

Integer localInteger = Integer.valueOf(100);

深入内部细节

查看如下一段代码

Integer i = null;
int j = i;

上述代码能够通过编译,但是在运行期显示NullPointerException。为什么会这样?

原因在于执行期间,编译程序会将上述代码展开为

Object localObject = null;
int i = localObject.intValue();

显而易见,这段代码试图让一个空引用操作intValue()方法,明显其没有此属性,因此抛出异常.

小结

作为语法糖,自动拆装箱确实减轻了程序员的负担,但同时也是一把双刃剑。在使用过程中应当注意,分析展开之后的真实真实情况。