5

我无法理解在以下代码中创建 obj 和 obj2 对象的方式的区别。特别是,我不确定如何将原语转换为对象。看看这里的其他一些问题,我认为这是不可能的。但以下程序编译并运行良好。在第一种情况下,输出为假,在第二种情况下,输出为真。

public class Test {

    public static void main(String args[]){

        Integer num = new Integer(3) ;
        Object obj = num;
        Integer[] integerArr = {1, 2, 3, 4};
        Object[] objArr = integerArr;
        boolean contains = false;

        for (int i = 0; i < objArr.length; i++){
            if (objArr[i] == obj){
                contains = true;
                break;
            }
        }

        System.out.println(contains);

        int num2 = 3 ;
        Object obj2 = num2;
        Integer[] integerArr2 = {1, 2, 3, 4};
        Object[] objArr2 = integerArr2;
        boolean contains2 = false;

        for (int i = 0; i < objArr2.length; i++){
            if (objArr2[i] == obj2){
                contains2 = true;
                break;
            }
        }

        System.out.println(contains2);
    }

}
4

4 回答 4

4

对象之间的==运算符测试身份(如果两个对象完全相同),而equals()方法测试相等(两个对象是否具有相同的值)。

大多数时候,你会对平等感兴趣。碰巧,您在问题中提供的示例实际上有效,因为Integer对象被缓存(通常在 -127 到 127 的范围内,尽管这是可配置的),但是如果您使用更大的数字测试身份,则测试很可能将失败。

例如,这将评估为true

Integer a = 127;
Integer b = 127;
a == b // true

而这将评估为false

Integer a = 128;
Integer b = 128;
a == b // false

底线:安全起见,始终equals()用于测试对象之间的相等性。

于 2013-03-06T00:32:38.190 回答
3

你必须从java.lang.Integer

public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

在第一种情况下,您创建一个新Integer对象,而在第二种情况下,编译器通过使用缓存为您进行转换。

/**
 * Cache to support the object identity semantics of autoboxing for values between
 * -128 and 127 (inclusive) as required by JLS.
 *
 * The cache is initialized on first usage.  The size of the cache
 * may be controlled by the -XX:AutoBoxCacheMax=<size> option.
 * During VM initialization, java.lang.Integer.IntegerCache.high property
 * may be set and saved in the private system properties in the
 * sun.misc.VM class.
 */

下面是相关的字节码,看看它如何最终调用Integer构造函数或Integer.valueOf

0: new #2; //class java/lang/Integer
3: dup
4: iconst_3
5: invokespecial #3; //Method java/lang/Integer."<init>":(I)V
8: astore_1
9: aload_1
10: astore_2
11: iconst_4
12: anewarray #2; //class java/lang/Integer
15: dup
16: iconst_0
17: iconst_1
18: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
21: aastore
...
90: iconst_3
91: istore 6
93: iload 6
95: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
98: astore 7
100: iconst_4
101: anewarray #2; //class java/lang/Integer
104: dup
105: iconst_0
106: iconst_1
107: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
110: aastore
111: dup
...
于 2013-03-06T00:33:22.153 回答
1

==如果 object1 和 object2 是引用类型,则 == 检查 object1 和 object2 是否都是对同一对象的引用。

equals如果你使用 object1.equals(object2) 那么它会比较对象的实际值

例子:

使用String.equals(String other)函数来比较字符串,而不是 == 运算符。

该函数检查字符串的实际内容,== 运算符检查对对象的引用是否相等。

于 2013-03-06T00:36:58.910 回答
0

在第二种情况下,您将原语int与对象Integer数组进行比较。JVM正在“解包”对象Integer并与原语进行比较。因此在这种情况下你确实得到了相等匹配。

在第一种情况下,您总是将一个对象与另一个对象进行比较,在您的示例中,它们永远不会相等。

于 2013-03-06T00:36:04.927 回答