关于自动装箱和对象相等/身份的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适用于’==’运算符。