比较Java中的整数值,奇怪的行为

比较Java中的整数值,奇怪的行为,java,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 ==

跟我走

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

你们觉得怎么样?什么可以解释这种情况?

您正在比较
整数
值,这些值是引用。你会通过自动装箱找到那些参考资料。对于某些值(保证为-128到127),JRE维护
Integer
对象的缓存。对于更高的值,它不会。发件人:

如果要装箱的值p为true、false、一个字节或\u0000到\u007f范围内的字符,或一个介于-128和127(包括-128和127)之间的整数或短数字,则让r1和r2为p的任意两个装箱转换的结果。r1==r2总是这样

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

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


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

当您对两个整数使用
=
时,自动装箱听起来很奇怪

如果您使用
equals()
方法,我会假设它在使用
Integer
时工作正常?我猜无论如何都会这样


您没有使用java 1.4或其他东西,是吗?

要正确比较整数,您需要使用
.equals()
或通过强制转换为
int
或调用
intValue()
来比较它们的基本值

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

编辑以说明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

@JAM:是的,可以强制转换为
int
,调用
intValue()
并比较结果,或者调用
equals()
。可能重复执行的操作
getIndex()
getSomeOtherIndex()
do?其他答案的可能重复正好说明了发生这种情况的原因:JVM缓存小的整数值。因此,当我比较(newinteger(12)==newinteger(12))[yields true]时,JVM为该值12的两侧返回相同的缓存对象。因此,事实上,对象是相同的。对于较大的值,会独立创建新对象,但不会发生这种情况。
    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