web-dev-qa-db-ja.com

Java null文字列は結果と等しい

Javaのstring.equalsがnull値でどのように機能するか、例外に問題があるか?3つのケース:

boolean result1,result2, result3;

    //1st case
    String string1 = null;
    String string2 = null;
    result = string1.equals(string2);
    //2nd case
    String string1 = "something";
    String string2 = null;
    result2 = string1.equals(string2);
    //3rd case 
    String string1 = null;
    String string2 = "something";
    result3 = string1.equals(string2);

結果の価値は何ですか?私はこの値を期待します:

result1はtrueです。
result2はfalseです。
result3はfalseです。

13
user1097772

デリファレンス(ドット、 '。')演算子を使用してインスタンス変数にアクセスしたり、インスタンスがnullの場合、インスタンスのメソッドを呼び出したりすることはできません。これを行うと、NullPointerExceptionが生成されます。

文字列比較では、nullでないことがわかっているものを使用するのが一般的です。たとえば、"something".equals(stringThatMayBeNull)などです。

37
sjr

実際、null変数でドット演算子を使用して非静的メソッドを呼び出すことはできません。

これにもかかわらず、すべてはObjectクラスのequals()メソッドのオーバーライドに依存しています。 Stringクラスの場合:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = offset;
            int j = anotherString.offset;
            while (n-- != 0) {
                if (v1[i++] != v2[j++])
                    return false;
            }
            return true;
        }
    }
    return false;
}

nullをパラメーターとして渡すと、両方の「if」が失敗し、falseが返されます。

あなたのケースの代替手段は、要件に合ったメソッドを構築することです:

public static boolean myEquals(String s1, String s2){
    if(s1 == null)
        return s2 == null;
    return s1.equals(s2);
}
12
elias

JDK 7以降を使用している場合は、Objects.equals()を使用して文字列やその他のオブジェクトを比較します。例外をスローせずにnullを処理します。詳細はこちら: how-do-i-compare-strings-in-Java

9
Erk

そのコードは、string1がnullであるときにNullPointerExceptionをスローし、nullオブジェクトに対してメソッドが暗黙的に呼び出される場合のように、そのコードに対してequalsを呼び出します。

文字列がnullかどうかを確認するには、equalsではなく==を使用します。

result1およびresult3はNullPointerExceptionsが原因で設定されませんが、result2はfalseになります(他の結果のコンテキスト外で実行した場合)。

3
FThompson

文字列の少なくとも1つがnullになる可能性がある場合に文字列を比較するときにNPEを防ぐには、nullセーフなStringUtils.equalsメソッドを使用します。

1
AniaG

ケース1とケース3でNullPointerExceptionが発生します。

Nullオブジェクトでメソッド(equals()など)を呼び出すことはできません。

1
Chip

NullPointerExceptionが発生するため、nullでドット演算子を使用することはできません。したがって、プログラムでtry..catchブロックを利用できます。これは問題を解決するための非常に大雑把な方法ですが、望ましい出力が得られます。

try {
   result = string1.equals(string2);
} catch (NullPointerException ex) {
   result = string2 == null; //This code will be executed only when string 1 is null
}
0
Sam