比较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 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
你们有什么感想? 什么会解释这样的事情?
您正在比较Integer
数值,它们是引用。 你通过自动装箱提出这些引用。 对于某些值(保证为-128到127),JRE维护一个Integer
对象的caching。 对于更高的值,它不会。 从JLS第5.1.7节 :
如果p的值是真,假,一个字节,或者范围在\ u0000到\ u00f之间的一个字符,或者在-128到127之间的一个int或者一个短数字,那么让r1和r2是任何两个拳击转换的p。 r1 == r2总是如此。
理想情况下,装箱一个给定的原始值p,总会产生一个相同的参考。 实际上,使用现有的实现技术可能是不可行的。 上面的规则是一个务实的妥协。 上面的最后一个条款要求某些常用值总是被装入不可区分的对象中。 实现可能会caching这些,懒惰或热切。 对于其他的值,这个公式不允许对程序员的盒装值的身份进行任何假设。 这将允许(但不要求)分享这些引用的一部分或全部。
这确保了在大多数情况下,行为将是所期望的,而不施加不适当的性能损失,特别是在小型设备上。 例如,内存限制较less的实现可能会caching所有char和short值,以及-32K到+ 32K范围内的int和long值。
道德:当你对底层的int
值感兴趣时,不要比较Integer
引用。 使用.equals()
或首先获取int
值。
为了正确地比较整数,你需要使用.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
听起来像是在使用==
两个整数时自动装箱的东西。
我会假设,如果你使用equals()
方法使用Integer
,它工作正常吗? 无论如何,这将是我的猜测。
你没有使用Java 1.4或者你是什么东西?