211

==2つを比較するときにいくつかの問題があることを私は知っていますStrings。それString.equals()はより良いアプローチのようです。さて、私はJUnitテストを行っており、私の傾向はを使用することassertEquals(str1, str2)です。これは、2つの文字列に同じコンテンツが含まれていることを表明するための信頼できる方法ですか?私はを使用assertTrue(str1.equals(str2))しますが、失敗した場合の期待値と実際の値を確認するメリットはありません。

関連するメモで、誰かが問題をわかりやすく説明するページまたはスレッドへのリンクを持っていますstr1 == str2か?

4

7 に答える 7

291

Javaで比較するときは、常に使用する必要があります。.equals()Strings

JUnitはメソッドを呼び出して、.equals()メソッドの同等性を判別しassertEquals(Object o1, Object o2)ます。

だから、あなたは間違いなく安全に使用できますassertEquals(string1, string2)。(StringsはObjectsであるため)

==との違いのいくつかに関するStackoverflowのすばらしい質問へのリンクを次に示します.equals()

于 2009-07-29T17:51:30.317 に答える
33

assertEqualsequals比較のためにメソッドを使用します。演算子assertSameを使用する別のアサートがあります。==

==文字列で使用すべきでない理由を理解するには、何をするのかを理解する必要があります==。それはIDチェックを行います。つまり、同じオブジェクトを参照しているa == bかどうかを確認します。これは言語に組み込まれており、その動作を異なるクラスで変更することはできません。一方、メソッドはクラスによってオーバーライドできます。(クラス内の)デフォルトの動作は演算子を使用してIDチェックを実行することですが、を含む多くのクラスは、代わりに「等価」チェックを実行するためにそれをオーバーライドします。の場合、同じオブジェクトを参照しているかどうかを確認する代わりに、abequalsObject==StringStringaba.equals(b)それらが参照するオブジェクトが両方ともまったく同じ文字を含む文字列であるかどうかを確認します。

類推時間:各Stringオブジェクトが何かが書かれた一枚の紙であると想像してください。「Foo」と書かれた2枚の紙と「Bar」と書かれたもう1枚の紙があるとしましょう。最初の2枚の紙を取り、==それらを比較するために使用するとfalse、本質的に「これらは同じ紙ですか?」と尋ねられるため、返されます。紙に書かれていることを見る必要さえありません。私がそれに(同じものを2回ではなく)2枚の紙を与えているという事実は、それが戻ることを意味しますfalseequalsただし、を使用すると、equalsメソッドは2枚の紙を読み取り、それらが同じこと( "Foo")を言っていることを確認するため、を返しtrueます。

文字列と混同されるのは、Javaには文字列を「インターン」するという概念があり、これはコード内の文字列リテラルに対して(効果的に)自動的に実行されるということです。これは、コードに2つの同等の文字列リテラルがある場合(それらが異なるクラスにある場合でも)、実際には両方が同じStringオブジェクトを参照することを意味します。これにより、==オペレーターtrueは予想よりも頻繁に戻るようになります。

于 2009-07-29T18:15:48.620 に答える
8

一言で言えば、同じ文字を含むが異なるオブジェクト(異なるメモリ位置)である2つのStringオブジェクトを持つことができます。==演算子は、2つの参照が同じオブジェクト(メモリ位置)を指していることを確認しますが、equals()メソッドは文字が同じかどうかを確認します。

通常、2つの文字列に同じ文字が含まれているかどうかを確認することに関心があり、同じメモリ位置を指しているかどうかは確認しません。

于 2009-07-29T18:15:06.187 に答える
6
public class StringEqualityTest extends TestCase {
    public void testEquality() throws Exception {
        String a = "abcde";
        String b = new String(a);
        assertTrue(a.equals(b));
        assertFalse(a == b);
        assertEquals(a, b);
    }
}
于 2009-07-29T17:54:28.233 に答える
3

JUnitassertEquals(obj1, obj2)は確かにを呼び出しますobj1.equals(obj2)

回避しようとしていることである(つまり、それを検証し、同じインスタンスを参照している)ものもassertSame(obj1, obj2)あります。obj1 == obj2obj1obj2

だからあなたは元気です。

于 2009-07-29T18:06:12.060 に答える
3

はい、それはテストのために常に使用されます。テストフレームワークは、これらのような比較に.equals()を使用する可能性が非常に高いです。

以下は「文字列の等式の間違い」を説明するリンクです。基本的に、Javaの文字列はオブジェクトであり、オブジェクトの同等性を比較する場合、通常、コンテンツではなくメモリアドレスに基づいて比較されます。このため、2つの文字列は、内容が同じであっても同じアドレスを占有しないため、印刷時に同じように見えても、正しく一致しません。

http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/

于 2009-07-29T17:48:48.527 に答える
0

「オペレーターは、2つが完全に同じである==かどうかを確認します。」ObjectsObject

http://leepoint.net/notes-java/data/strings/12stringcomparison.html

StringObjectJavaであるため、比較ルールのそのカテゴリに分類されます。

于 2009-07-29T17:51:44.653 に答える