26

与我同行 ..

Integer x = 23;
Integer y = 23;

if (x == y)
    System.out.println("what else");      // All is well as expected
else
    System.out.println("...");

尽管

Integer x = someObject.getIndex();
Integer y = someOtherObject.getSomeOtherIndex();

if (x == y)
    System.out.println("what else");  
else
    System.out.println("...");        // Prints this 

嗯...我尝试转换为 int

int x = someObject.getIndex();
int y = someOtherObject.getSomeOtherIndex()

if (x == y)       
    System.out.println("what else");   // works fine
else
    System.out.println("...");  

它们都是整数吗?

System.out.println(x.getClass().getName());              // java.lang.Integer
System.out.println(y.getClass().getName());              // java.lang.Integer
System.out.println(someObject.getIndex());               // java.lang.Integer
System.out.println(someOtherObject.getSomeOtherIndex()); // java.lang.Integer

你们有什么感想?什么可以解释这样的事情?

4

3 回答 3

45

您正在比较Integer值,即参考值。您将通过自动装箱提出这些参考。对于某些值(保证为 -128 到 127),JRE 维护Integer对象缓存。对于更高的值,它不会。从JLS 的第 5.1.7 节

如果被装箱的值 p 是真、假、一个字节或 \u0000 到 \u007f 范围内的一个字符,或者一个介于 -128 和 127(含)之间的 int 或短数字,则令 r1 和 r2 为p 的任意两个拳击转换。r1 == r2 总是如此。

理想情况下,对给定的原始值 p 进行装箱将始终产生相同的参考。在实践中,使用现有的实现技术这可能是不可行的。上述规则是一种务实的妥协。上面的最后一个条款要求某些常见的值总是被装箱到无法区分的对象中。实现可能会懒惰地或急切地缓存这些。对于其他值,此公式不允许程序员对装箱值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。

这确保了在最常见的情况下,行为将是期望的行为,而不会造成过度的性能损失,尤其是在小型设备上。例如,内存限制较少的实现可能会缓存所有 char 和 short 值,以及 -32K 到 +32K 范围内的 int 和 long 值。

Integer道德:当您对潜在int价值感兴趣时,不要比较参考资料。首先使用.equals()或获取int值。

于 2012-04-03T22:00:40.073 回答
13

要正确比较整数,您需要通过强制转换或调用它们来使用.equals()或比较它们的原始值。intintValue()

Using==检查两个 Integer 是否是相同的 Object,而不是检查它们是否包含相同的数值

    Integer a = new Integer(1);
    Integer b = new Integer(1);

    System.out.println(a.equals(b));                  //true
    System.out.println((int)a == (int)b);             //true
    System.out.println(a.intValue() == b.intValue()); //true
    System.out.println(a == b);                       //false

编辑以说明 JLS 关于自动装箱的 Jon 的观点:

    Integer a = 1;
    Integer b = 1;
    System.out.println(a.equals(b));                  //true
    System.out.println((int)a == (int)b);             //true
    System.out.println(a.intValue() == b.intValue()); //true
    System.out.println(a == b);                       //true

相对:

    Integer a = 128;
    Integer b = 128;
    System.out.println(a.equals(b));                  //true
    System.out.println((int)a == (int)b);             //true
    System.out.println(a.intValue() == b.intValue()); //true
    System.out.println(a == b);                       //false
于 2012-04-03T22:02:09.367 回答
1

==当您在两个整数上使用时,听起来自动装箱很时髦。

Integer如果您使用该方法,我会假设它在使用时可以正常工作equals()?无论如何,这将是我的猜测。

您没有使用 java 1.4 还是什么?

于 2012-04-03T22:02:02.787 回答