关于自动装箱和对象平等/身份的Java问题

时间:2010-07-28 10:09:49

标签: java integer autoboxing

public class Main { 
    /** 
      * @param args the command line arguments */ 
    public static void main(String[] args) { 
        // TODO code application logic here
        int a1 = 1000, a2 = 1000; 
        System.out.println(a1==a2);//=>true 
        Integer b1 = 1000, b2 = 1000;
        System.out.println(b1 == b2);//=>false 
        Integer c1 = 100, c2 = 100; 
        System.out.println(c1 == c2);//=>true 
    }

}

为什么b1 == b2为false且c1 == c2为真?

7 个答案:

答案 0 :(得分:37)

阅读this

Java对Integer使用-128到127之间的范围。

这意味着如果您使用Integer创建Integer i = 42;并且其值介于-128和128之间,则会创建 no 新对象,但池中相应的对象是回。这就是为什么c1确实相同c2

我假设您知道==在应用于对象时比较引用而不是值。)

答案 1 :(得分:11)

已经给出了正确的答案。但只是加上我的两分钱:

Integer b1 = 1000, b2 = 1000;

这是糟糕的代码。应通过构造函数或工厂方法将对象初始化为对象。 E.g。

 // let java decide if a new object must be created or one is taken from the pool
Integer b1 = Integer.valueOf(1000);

 // always use a new object
 Integer b2 = new Integer(1000);

此代码

Integer b1 = 1000, b2 = 1000;
另一方面,

意味着Integer是一个原始的,它不是。实际上你所看到的是

的捷径
Integer b1 = Integer.valueOf(1000), b2 = Integer.valueOf(1000);

和Integer只汇集-127到127之间的对象,因此在这种情况下它将创建两个新对象。因此,虽然1000 = 1000,但是b1!= b2。这是我讨厌自动拳击的主要原因。

答案 2 :(得分:2)

你可以在这里找到答案:

在第6个答案中

Strangest language feature

编辑:对不起,答案不是很好。关键是==比较引用,而不是与Integer一起使用时的值。但是使用int“==”表示等于。

答案 3 :(得分:2)

因为Integer是针对像枚举这样的一些低数字所以总是存在相同的实例。但是更高的数字会创建Integer的新实例,而operator ==会比较它们的引用

答案 4 :(得分:2)

  public static Integer valueOf(int i) {
      final int offset = 128;
      if (i >= -128 && i <= 127) { // must cache
          return IntegerCache.cache[i + offset];
      }
       return new Integer(i);
    }

因此,你在一个案件中是真的,在其他案件中是假的!

答案 5 :(得分:0)

您想要的答案是here

答案 6 :(得分:0)

如果在使用'=='运算符进行等式检查时,autounboxing也起作用,你可以写:

    Long notNullSafeLong1 = new Long(11L)
    Long notNullSafeLong2 = new Long(22L)
    if ( notNullSafeLong1 == notNullSafeLong2) {
      do suff

这需要为==实现覆盖,以便null == someLong为false,特殊情况Null == Null为true。相反,我们必须使用equal()和test

    Long notNullSafeLong1 = new Long(11L)
    Long notNullSafeLong2 = new Long(22L)
    if ( (notNullSafeLong1 == null && notNullSafeLong2 == null) || 
      (notNullSafeLong1 != null && notNullSafeLong2 != null & 
        notNullSafeLong1.equals(notNullSafeLong2)) {
      do suff    

这比第一个例子更冗长 - 如果autounboxing适用于'=='运算符。