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 的输出,但是如果我们将ij 的值更改为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 的相关段落:

如果被装箱的值ptrue, 范围内的falsebytechar \u0000\u007f,或者一个 int 或 short 介于 -128 和 127 之间的数字,然后让 r1r2 是任意两个的结果 p的拳击转换。它总是 r1 == r2.

的情况

请注意,这也描述了其他类型发生的情况。

【讨论】:

【参考方案5】:

基本上,-127 和 127 之间的整数被“缓存”,这样当您使用这些数字时,您总是在内存中引用相同的数字,这就是您的 == 有效的原因。

任何超出该范围的整数都不会被缓存,因此引用不一样。

【讨论】:

以上是关于Java Wrapper 相等性测试的主要内容,如果未能解决你的问题,请参考以下文章

在 Realm 中测试相等性

用 Jest 测试匿名函数相等性

*通过共享* JavaScript 对象测试深度相等性

C ++中派生类的相等性测试[重复]

如何在 JSF 中测试枚举相等性?

如何使用 xcttest 测试对象相等性?