自动装箱、拆箱是java的语法糖,在编译之后被转化成了对应的包装和还原方法,虽然这些语法糖看起来很简单,但是也有需要注意的地方,如下示例:
public classOne{
publicstaticvoidmain(String[] args)
{
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
System.out.println(c == d);
System.out.println(e == f);
System.out.println(c == (a + b));
System.out.println(c.equals(a + b));
System.out.println(g == (a + b));
System.out.println(g.equals(a + b));
}
}
先思考一下上面代码的输出。可以在Eclipse里运行一下以验证自己的想法。
注意:包装类的“==”运算在不遇到算术运算的情况下不会自动拆箱,以及他们的equals()方法不处理数据的转型。
下面将刚刚示例中的代码编译成class文件,然后再通过字节码反编译工具进行反编译,以证实上述注意点。(反编译工具链接http://jd.benow.ca/)
importjava.io.PrintStream;
public class One
{
public static void main(String[] args)
{
//自动装箱
Integer a = Integer.valueOf(1);
Integer b = Integer.valueOf(2);
Integer c = Integer.valueOf(3);
Integer d = Integer.valueOf(3);
Integer e = Integer.valueOf(321);
Integer f = Integer.valueOf(321);
Long g = Long.valueOf(3L);
System.out.println(c == d);
System.out.println(e == f);
//遇到算术运行+,所以自动拆箱
System.out.println(c.intValue() == a.intValue() + b.intValue());
System.out.println(c.equals(Integer.valueOf(a.intValue() +b.intValue())));
//遇到算术运行+,所以自动拆箱
System.out.println(g.longValue() == a.intValue() + b.intValue());
//equals()方法不处理数据的转型
System.out.println(g.equals(Integer.valueOf(a.intValue() +b.intValue())));
}
}
提示:前两行输出的结果不一样,通过查看valueOf()函数的实现,可以很容易理解。
本文摘抄自《深入理解Java虚拟机》一书。