5

次のコードでは、objオブジェクトとobj2オブジェクトの作成方法の違いを理解できません。特に、プリミティブがオブジェクトにどのようにキャストされるかはわかりません。ここで他の質問のいくつかを見て、私はこれが不可能だと思いました。ただし、次のプログラムはコンパイルされ、正常に実行されます。前者の場合、出力はfalseであり、後者の場合、出力はtrueです。

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

オブジェクト間の==演算子は同一性(2 つのオブジェクトがまったく同じかどうか)equals()をテストしますが、メソッドは等価性(2 つのオブジェクトが同じ値を持つかどうか) をテストします。

ほとんどの場合、平等に関心があります。偶然にも、オブジェクトがキャッシュされているため(通常は -127 から 127 の範囲で、これは構成可能です)、質問で提供した例は実際に機能Integerしますが、より大きな数を使用して ID をテストした場合、テストが失敗します。

たとえば、これは次のように評価され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オブジェクトを作成し、2 番目のケースではコンパイラがキャッシュを使用して変換を行います。

/**
 * 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

int2 番目のケースでは、プリミティブをオブジェクトInteger配列と比較しています。JVMはオブジェクトを「アンラップ」Integerし、プリミティブと比較しています..したがって、その場合、同等の一致が得られます。

最初のケースでは、常にオブジェクトを別のオブジェクトと比較しています。あなたの例では、これらが等しくなることはありません。

于 2013-03-06T00:36:04.927 に答える