1

可能重复:
在 Java 中使用 == 运算符比较包装器对象

java版本1.6.0_26

来自SCJP 考试准备的书:

为了节省内存,以下的两个实例[-128 和 127 中的短整数和整数,以及其他一些但无关紧要的问题] 包装对象(通过 boixng 创建),当它们的原始值是相同。

我做了什么:

如果我们像这样比较两个从 -128 到 127 的整数:

1. Integer i1 = 10;
2. Integer i2 = 10;
3. System.out.println(i1 == i2); // true

但是为什么同样给我们“假”或者可能是不一样的东西:

4. Integer i3 = new Integer(10);
5. Integer i4 = new Integer(10);
6. System.out.println(i3 == i4); // false

我的问题:

1)我们是否在第一行代码中进行隐式装箱?

2) 为什么第 3 行和第 6 行代码给了我们不同的结果?

4

4 回答 4

8

我们是否在第一行代码中进行隐式装箱?

Yes

2) 为什么第 3 行和第 6 行代码给了我们不同的结果?

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);
}

相反,当您调用时new Integer(10);,它正在创建一个全新的对象,因此具有相同整数值的两个不同对象将指向不同的内存地址

于 2012-12-27T06:30:14.193 回答
3
1) Does on the 1st line of code we make implicit boxing?

是的。它被称为自动装箱

2) Why the 3rd and 6th lines of code give us different results?

== 实际上检查两个变量是否具有完全相同的值。请注意,原始变量包含您看到的内容,但引用变量包含它所拥有的对象的地址。

当 == 用于比较原始与包装器时,包装器将被解包并且比较将是原始到原始的,因此它将始终为真,因为它是原始比较而不是对象比较。所以这就是为什么

System.out.println(i1 == i2);

会是真的。

但是在第 6 行。

System.out.println(i3 == i4);

您正在比较两个对象,除非对象具有相同的引用,否则它不会是真的。如果你使用 .equals 方法,你可以得到真实的。尝试

System.out.println(i3.equals(i4));
于 2012-12-27T06:29:16.920 回答
1

In your first example, the compiler is using boxing to assign the variables. In this case, i1/i2 are constants (a bit like static final objects).

In the second example, you create two instances of an Integer, hence they are never the same.

于 2012-12-27T06:27:26.733 回答
0

第 6 行显示为 false,因为它正在比较查看引用是否指向同一个对象i3i4在这种情况下,它不是。因此false.

如果同时涉及包装器和基元,则自动装箱和拆箱就会出现。这里i3i4都是包装对象,因此它将被视为任何其他对象POJO

自动装箱仅在同时涉及包装器对象和原语时才会发生,

例如

int primitive = 10;
Integer wrapper = new Integer(10);
System.out.println(primitive == wrapper); //true

True在上面的比较中打印==原始的值与包装器的状态进行比较。

于 2012-12-27T06:29:30.140 回答