在Java中使用==运算符来比较包装器对象

did*_*ido 51 java integer equals wrapper operator-keyword

我正在阅读Kathy Sierra和Bert Bates的SCJP Java 6,这本书让我很困惑.在页245上,他们在下面说明以下代码.

Integer i1 = 1000;
Integer i2 = 1000;
if(i1 != i2)
System.out.println("different objects");

//Prints output
different objects
Run Code Online (Sandbox Code Playgroud)

然后在下一页上,他们有以下代码

Integer i3 = 10;
Integer i4 = 10;
if(i3 == i4)
System.out.println("same objects");

//Prints output
same objects
Run Code Online (Sandbox Code Playgroud)

我很困惑!当我自己尝试这个时,似乎你不能使用==来比较你使用equals()方法的方式.即使整数变量设置为相同的值(即10),使用==总是给我'假'.我对么?使用==来比较相同的Integer对象(具有相同的值)将始终导致'false'

das*_*ght 62

答案的关键是称为对象实习.爪哇实习生小数目(小于128),因此,所有的实例Integer(n)n在实习范围是相同的.大于或等于128的数字未被实现,因此Integer(1000)对象彼此不相等.

  • 请注意,只有从文字,autoboxing和`Integer.valueOf()`获得的对象是实习对象,而用`new Integer`构造的对象总是不同的对象 (10认同)
  • 哇!我也刚刚看到了。为什么??这太令人困惑了。这背后的原因是什么? (2认同)
  • @dido实习整数背后的原因之一是试图节省内存并在一定程度上节省时间.当`Integer`对象用作哈希映射中的键或哈希集中的对象时,小整数的百分比不成比例地大.通过实习它们,您可以跳过重新分配内存以保存彼此相同的不可变对象的相同副本,并通过首先检查引用相等性来使相等比较更快完成.最重要的是,它在CPU周期方面几乎没有任何成本,因此这是一个容易做出的决定. (2认同)

Ste*_*Kuo 17

如果您查看源代码,Integer您将看到Integer.valueOf(int) 池的所有值都为-128到127.原因是经常使用小的Integer值,因此值得汇总/缓存.

直接来自Integer.java:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}
Run Code Online (Sandbox Code Playgroud)

请注意,此池是特定于实现的,并且无法保证池化范围.

关于实习的答案在概念上是正确的,但在术语上是不正确的.在Java中实习通常意味着Java运行时正在执行池化(例如String的实习生).在Integer的情况下,正在进行池化的类本身.没有涉及JVM魔法.


has*_*vec 7

关于实习的上述答案是正确的.如果您这样做,可以考虑一些事情:

Integer i3 = new Integer(10);
Integer i4 = new Integer(10);
Run Code Online (Sandbox Code Playgroud)

由于您明确地创建了新对象,因此您将不会拥有新对象.如果你按如下方式编写代码,它将被实习:

Integer i3 = Integer.valueOf(10);
Integer i4 = Integer.valueOf(10);
Run Code Online (Sandbox Code Playgroud)

它们现在将再次成为同一个对象.如果您查看src.zip文件中Integer.java类中的valueOf方法,您可以看到它检查的位置,以查看int的值是否在-128到127之外,它会调用新的Integer类.它从缓存中加载它.


归档时间:

查看次数:

15932 次

最近记录:

7 年,2 月 前