Java自动装箱的陷阱

Java的自动装箱与拆箱是通过在编译时添加,Integer.valueOf()与Interger.iniValue()实现的,也就是所谓的语法糖。虽然看起来很简单,但是也需要我们注意一些地方:
如下代码:

package com.example;

public class MyClass {


    public static void main(String[] args) throws Throwable {
        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));
    }


}

结果如下

true
false
true
true
true
false

可能这个结果让人很糊涂,下面我反编译代码,看看实际代码是怎么样的。

package com.example;

import java.io.PrintStream;

public class MyClass
{
  public static void main(String[] args)
    throws Throwable
  {
    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());
    System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue())));
  }
}

这里面有几点需要注意:

1.如果包装类的“==”运算在不遇到算术运算符的情况下不会自动拆箱。
2。包装类的equals()方法不处理类型转化管理。

关于Lang的equals方法如下,在最后一个比较中,由于自动装箱为Interger类型不属于Long所以返回了false

    public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }

建议大家在实际编码中尽量避免这样使用自动拆箱与装箱。

你可能感兴趣的:(java)