2012-12-27 54 views
1

可能重复:
Using == operator in Java to compare wrapper objects原始包装比较

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行代码给了我们不同的结果?

+0

你'对了!这是重复的。 – user485553

回答

7

在第一行我们做隐式装箱的代码?

Yes 

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

Integer.valueOf(int)池的所有值从-128到127

的原因是,小的整数值经常使用并且在创造所有这些值的新对象是没有意义的,每次我们需要一个对象。因此,它们被创建为“实体”对象,并且对这样的整数值的所有引用将指向相同的存储器地址。从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);,它正在一个全新的对象,因此两次与相同的整数值不同的对象会指向不同的存储器地址

+0

所以,如果我写Integer i1 = 10;编译器用Integer隐式取代它i1 = Integer.valueOf(10);这意味着如果我的数字范围从-128到127(或您的IntegerCache.high),它给了我已经存在的Integer对象。这是我们在==比较中得到真实的主要原因。 – user485553

1

在第一个示例中,编译器正在使用装箱来分配变量。在这种情况下,i1/i2是常量(有点像静态最终对象)。

在第二个示例中,您创建了Integer的两个实例,因此它们从不相同。

2
1) Does on the 1st line of code we make implicit boxing? 

是。其所谓的Auto-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); 

你比较两个对象,除非对象有它不会是真实的相同的参考。如果你使用。等于你可以变成真的方法。尝试

System.out.println(i3.equals(i4)); 
0

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

如果同时包含包装和基本体,自动装箱和取消装箱将进入画面。这里既有i3i4是包装对象,因此,它将被视为任何其它POJO

自动装箱只发生,如果有两个包装对象和一个图元参与,

例如

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

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

+0

我知道它比较两个参考。但我不明白它为什么这样做? – user485553