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

Jam*_*sev 24 java

与我同行 ..

Integer x = 23;
Integer y = 23;

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

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

if (x == y)
    System.out.println("what else");  
else
    System.out.println("...");        // Prints this 
Run Code Online (Sandbox Code Playgroud)

嗯......我尝试转换为int

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

if (x == y)       
    System.out.println("what else");   // works fine
else
    System.out.println("...");  
Run Code Online (Sandbox Code Playgroud)

他们都是整数?

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
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 44

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

如果被装箱值p为真,假,字节,或在范围\ u0000的一个char到\ u007f,或int或-128和127(含)之间的短号码,然后让r1和r2是的结果p的任何两个拳击转换.始终是r1 == r2的情况.

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

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

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

  • @JAM:是的,要么转换为`int`,要调用`intValue()`并比较结果,要么调用`equals()`. (2认同)

DNA*_*DNA 13

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

使用==检查两个Integers是否是同一个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
Run Code Online (Sandbox Code Playgroud)

编辑说明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
Run Code Online (Sandbox Code Playgroud)

与:

    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
Run Code Online (Sandbox Code Playgroud)