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

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真?

读这个 。

Java在-128到127之间使用Integer

这意味着如果你用Integer i = 42;创建一个Integer Integer i = 42; 并且它的值介于-128和128之间, 不会创建新对象,但会返回池中相应的对象。 这就是c1确实 c2 相同的原因。

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

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

 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 b1 = Integer.valueOf(1000), b2 = Integer.valueOf(1000); 

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

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

你可以在这里找到答案:

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

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

  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); } 

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

你想要的答案就在这里

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

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

这将需要实现==的覆盖,以便null == someLong为false,特殊情况Null == Null为true。 相反,我们必须使用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 

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