18
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假的和c1 == c2真的?

4

7 回答 7

38

这个

Java在 -128 到 127 的范围内为s 使用一个池。Integer

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

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

于 2010-07-28T10:14:06.270 回答
12

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

Integer b1 = 1000, b2 = 1000;

这是糟糕的代码。对象应该通过构造函数或工厂方法初始化为对象。例如

 // 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。这就是我讨厌自动装箱的主要原因。

于 2010-07-28T10:53:47.640 回答
2

你可以在这里找到答案:

第 6 个答案中最奇怪的语言特征

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

于 2010-07-28T10:13:57.237 回答
2

因为 Integer 用于枚举等一些低数字,所以总是有相同的实例。但是更大的数字会创建 Integer 的新实例,并且 operator == 会比较它们的引用

于 2010-07-28T10:14:48.887 回答
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);
    }

因此,您在一种情况下为真,在另一种情况下为假!

于 2012-07-13T12:03:09.060 回答
0

你想要的答案在这里

于 2010-07-28T10:11:32.470 回答
0

如果在使用 '==' 运算符进行相等性检查时自动拆箱也有效,您可以编写:

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

这将需要实现对 == 的覆盖,以便 null==someLong 为假,而特殊情况 Null==Null 为真。相反,我们必须使用 equal() 并测试 null

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

这比第一个示例更详细 - 如果自动拆箱对 '==' 运算符有效。

于 2013-08-22T11:34:24.230 回答