Java Wrapper 相等性测试
Posted
技术标签:
【中文标题】Java Wrapper 相等性测试【英文标题】:Java Wrapper equality test 【发布时间】:2010-10-02 04:15:40 【问题描述】: public class WrapperTest
public static void main(String[] args)
Integer i = 100;
Integer j = 100;
if(i == j)
System.out.println("same");
else
System.out.println("not same");
上面的代码在运行时给出了same
的输出,但是如果我们将i
和j
的值更改为1000,则输出将更改为not same
。当我为 SCJP 做准备时,需要弄清楚这背后的概念。谁能解释一下这种行为。谢谢。
【问题讨论】:
非常有趣的问题,我不知道 Java 会这样。我倾向于尽可能使用 equals(),所以我很幸运能够避免这个问题。 【参考方案1】:这与平等和自动装箱有关:http://web.archive.org/web/20090220142800/http://davidflanagan.com/2004/02/equality-and-autoboxing.html
【讨论】:
【参考方案2】:您的代码无法编译。这是我得到的:
线程“main”java.lang.Error 中的异常:未解决的编译问题: 类型不匹配:无法从 int 转换为 Integer 类型不匹配:无法从 int 转换为 Integer
at WrapperTest.main(WrapperTest.java:5)
变量 i 和 j 是 Integer 对象的实例。不要使用“==”运算符比较对象的实例,而是使用“equals”方法。
问候
【讨论】:
我猜你使用的是 java 1.4.. 试试 Java 1.5【参考方案3】:在 Java 中,-128 到 127(含)之间的整数通常由同一个 Integer 对象实例表示。这是通过使用称为 IntegerCache 的内部类来处理的(包含在 Integer 类中,例如在调用 Integer.valueOf() 时或在自动装箱期间使用):
private static class IntegerCache
private IntegerCache()
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
另请参阅:http://www.owasp.org/index.php/Java_gotchas
【讨论】:
【参考方案4】:@tunaranch 是正确的。这与Python question 中的问题相同。要点是 Java 为从 -128 到 127 的整数保留一个对象(Python 是 -5 到 256),并且每次您请求时都返回相同的对象。如果你要求一个超出这个固定范围的整数,它每次都会给你一个新对象。
(回想一下==
返回两个对象是否实际上相同,而equals
比较它们的内容。)
编辑:这是来自Section 5.1.7 的Java Language Specification 的相关段落:
如果被装箱的值p是
的情况true
, 范围内的false
、byte
、char
\u0000
到\u007f
,或者一个 int 或 short 介于 -128 和 127 之间的数字,然后让 r1 和 r2 是任意两个的结果 p的拳击转换。它总是 r1 == r2.
请注意,这也描述了其他类型发生的情况。
【讨论】:
【参考方案5】:基本上,-127 和 127 之间的整数被“缓存”,这样当您使用这些数字时,您总是在内存中引用相同的数字,这就是您的 ==
有效的原因。
任何超出该范围的整数都不会被缓存,因此引用不一样。
【讨论】:
以上是关于Java Wrapper 相等性测试的主要内容,如果未能解决你的问题,请参考以下文章