比较Java中的Integer值,奇怪的行为

时间:2012-04-03 21:58:51

标签: java

和我一起走..

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

你们觉得怎么样?什么可以解释这样的事情?

3 个答案:

答案 0 :(得分:44)

您正在比较Integer值,这些值是参考值。您通过自动装箱提出了这些参考资料。对于某些值(保证为-128到127),JRE维护Integer个对象的缓存。对于更高的值,它没有。来自section 5.1.7 of the JLS

  

如果装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或者介于-128和127(含)之间的整数或短数,则让r1和r2为p的任意两次拳击转换的结果。始终是r1 == r2。

的情况      

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

     

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

道德:当您对基础Integer值感兴趣时,不要比较int个引用。使用.equals()或首先获取int值。

答案 1 :(得分:13)

要正确比较整数,您需要使用.equals()或通过转换为int或在其上调用intValue()来比较其原始值。

使用==检查两个整数是否是相同的对象,而不是它们是否包含相同的数值

    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

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

    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

答案 2 :(得分:1)

当你在两个整数上使用==时,听起来像是自动装箱的时髦。

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

你没有使用java 1.4或者你在做什么?