java陷阱之自动装箱[Java]
下面一段代码会得到什么样的结果呢?
public static void main(String[] args) {
Integer a=1;
Integer b=2;
Integer c=3;
Integer d=3;
Integer e=127;
Integer f=127;
Integer e2=128;
Integer f2=128;
Long g=3L;
System.out.println(c==d);
System.out.println(e==f);
System.out.println(e2==f2);
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));
}
结果是
true
true
false
true
true
true
false
有些出乎意料吧,有以下几点说明我就大概明白了:
1. java在对int型数据自动装箱为Integer对象的时候,如果值在-128-127之间,则会在内存中公用相同对象。比如前面的
Integer e=127;
Integer f=127;
中,e和f其实是引用了同一个对象。
JVM这样做的原因其实很好理解,就如同设置了字符串池一样,可能是他们通过统计发现java对int的定义很大部分都是在-128-127之间,并且通过性能分析发现装箱操作在这部分的开销占据很大一部分。
2. 包装类的“==”运算在没有遇到算术运算的时候是不会自动拆箱的。
3. Object.equals(Object obj)方法会先判断obj对象是否是该Object类型,如果不是,直接返回false;如果是则通过类型转换再进行比较其值。可以参考下面的Integer类的equals代码
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}