Ist die Methode assertEquals von Java zuverlässig?

Lesezeit: 5 Minuten

Benutzer-Avatar
Teile durch Helden

ich weiß das == hat einige Probleme, wenn man zwei vergleicht Strings. Es scheint, dass String.equals() ist ein besserer Ansatz. Nun, ich mache JUnit-Tests und meine Neigung ist es, es zu verwenden assertEquals(str1, str2). Ist dies ein zuverlässiger Weg, um zu behaupten, dass zwei Strings denselben Inhalt enthalten? ich würde … benutzen assertTrue(str1.equals(str2))aber dann haben Sie nicht den Vorteil, zu sehen, was die erwarteten und tatsächlichen Werte bei einem Fehler sind.

Hat in diesem Zusammenhang jemand einen Link zu einer Seite oder einem Thread, der die Probleme mit erklärt str1 == str2?

  • Wenn Sie sich nicht sicher sind, können Sie den Code oder das Javadoc lesen. Übrigens, wenn Sie testen möchten, dass es sich um dasselbe Objekt handelt, können Sie assertSame verwenden.

    – Peter Lawrey

    10. Dezember 2009 um 20:51 Uhr

  • Wenn str1 und str2 null sind, ist assertEquals() wahr, aber assertTrue(str1.equals(str2)) löst eine Ausnahme aus. Das erste Beispiel gibt auch eine nützliche Fehlermeldung wie den Inhalt von str1 und str2 aus, das zweite nicht.

    – Peter Lawrey

    20. Januar 2010 um 20:49 Uhr

Benutzer-Avatar
jjnguy

Du solltest stets verwenden .equals() beim vergleichen Strings auf Java.

JUnit ruft die auf .equals() Methode, um die Gleichheit in der Methode zu bestimmen assertEquals(Object o1, Object o2).

Sie sind also auf jeden Fall sicher in der Anwendung assertEquals(string1, string2). (Da Strings sind Objects)

Hier ist ein Link zu einer großartigen Stackoverflow-Frage zu einigen der Unterschiede zwischen == und .equals().

  • IIRC assertEquals() ist erfolgreich, wenn beide Zeichenfolgen null sind. Wenn Sie dies nicht möchten, rufen Sie auch assertNotNull() auf.

    – finnw

    29. Juli 2009 um 18:01 Uhr

  • Wenn Sie auf == testen möchten, können Sie außerdem assertSame() aufrufen.

    – James

    29. Juli 2009 um 18:37 Uhr

  • Ich würde nicht sagen stets; Manchmal ist Referenzgleichheit erwünscht, sogar für Strings.

    – Karu

    14. August 2014 um 12:33 Uhr

Benutzer-Avatar
Laurence Gonsalve

assertEquals nutzt die equals Methode zum Vergleich. Es gibt eine andere Behauptung, assertSamedie die verwendet == Operator.

Um zu verstehen warum == sollte nicht mit Zeichenfolgen verwendet werden, die Sie verstehen müssen == tut: es führt eine Identitätsprüfung durch. Das ist, a == b überprüft, ob a und b beziehen sich auf die gleiches Objekt. Es ist in die Sprache eingebaut und sein Verhalten kann nicht von verschiedenen Klassen geändert werden. Das equals Die Methode hingegen kann von Klassen überschrieben werden. Während sein Standardverhalten (in der Object Klasse) besteht darin, eine Identitätsprüfung mit der durchzuführen == Betreiber, viele Klassen, darunter String, überschreiben Sie es, um stattdessen eine “Äquivalenz”-Prüfung durchzuführen. Im Falle des Stringanstatt zu prüfen, ob a und b beziehen sich auf dasselbe Objekt, a.equals(b) überprüft, ob die Objekte, auf die sie verweisen, beide Zeichenfolgen sind, die genau die gleichen Zeichen enthalten.

Analogiezeit: Stellen Sie sich das vor String Objekt ist ein Stück Papier, auf dem etwas geschrieben steht. Nehmen wir an, ich habe zwei Zettel mit der Aufschrift „Foo“ und einen mit der Aufschrift „Bar“. Wenn ich die ersten beiden Zettel nehme und verwende == um sie zu vergleichen, wird es zurückkehren false weil es im Wesentlichen fragt: “Sind dies dasselbe Stück Papier?”. Er muss sich nicht einmal ansehen, was auf dem Papier steht. Die Tatsache, dass ich ihm zwei Zettel gebe (und nicht zweimal denselben), bedeutet, dass er zurückkommen wird false. Wenn ich benutze equalsjedoch die equals -Methode liest die beiden Zettel und sieht, dass sie dasselbe sagen (“Foo”), und so wird sie zurückkehren true.

Das Verwirrende an Strings ist, dass Java ein Konzept zum “Internieren” von Strings hat, und dies wird (effektiv) automatisch für alle String-Literale in Ihrem Code ausgeführt. Das bedeutet, dass, wenn Sie zwei äquivalente Zeichenfolgenliterale in Ihrem Code haben (selbst wenn sie in verschiedenen Klassen sind), sie beide auf dasselbe verweisen String Objekt. Das macht die == Bedienerrückgabe true häufiger als man erwarten würde.

  • “Das heißt, a == b prüft, ob a und b dasselbe Objekt sind.” Technisch wird überprüft, ob a und b auf dasselbe Objekt REFEREN, da a und b Referenzen sind. Es sei denn, ich liege sehr falsch.

    – Bob

    3. Juni 2015 um 18:37 Uhr

  • @ user1903064 das ist richtig. Da nicht primitive Variablen nur Referenzen in Java enthalten können, ist es üblich, die zusätzliche Ebene der Indirektion zu überspringen, wenn man über sie spricht, aber ich stimme zu, dass es in diesem Fall vorteilhafter ist, expliziter zu sein. Ich habe die Antwort aktualisiert. Danke für den Vorschlag!

    – Laurence Gonsalves

    4. Juni 2015 um 2:02 Uhr

Kurz gesagt – Sie können zwei String-Objekte haben, die dieselben Zeichen enthalten, aber unterschiedliche Objekte sind (an verschiedenen Speicherorten). Der Operator == prüft, ob zwei Verweise auf dasselbe Objekt (Speicherort) zeigen, aber die Methode equals() prüft, ob die Zeichen gleich sind.

Normalerweise interessiert Sie, ob zwei Strings dieselben Zeichen enthalten, nicht ob sie auf denselben Speicherplatz zeigen.

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);
    }
}

Die JUnit assertEquals(obj1, obj2) ruft tatsächlich an obj1.equals(obj2).

Es gibt auch assertSame(obj1, obj2) was tut obj1 == obj2 (dh bestätigt das obj1 und obj2 verweisen auf die gleich Instanz), was Sie vermeiden möchten.

Also geht es dir gut.

Benutzer-Avatar
Sowiut

Ja, es wird die ganze Zeit zum Testen verwendet. Es ist sehr wahrscheinlich, dass das Testframework .equals() für solche Vergleiche verwendet.

Unten ist ein Link, der den “String-Gleichheitsfehler” erklärt. Im Wesentlichen sind Zeichenfolgen in Java Objekte, und wenn Sie die Gleichheit von Objekten vergleichen, werden sie normalerweise auf der Grundlage der Speicheradresse und nicht des Inhalts verglichen. Aus diesem Grund belegen zwei Zeichenfolgen nicht dieselbe Adresse, selbst wenn ihr Inhalt identisch ist, sodass sie nicht korrekt übereinstimmen, obwohl sie beim Drucken gleich aussehen.

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

Benutzer-Avatar
jjnguy

“Das == Bediener prüft, ob zwei Objects sind genau gleich Object.”

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

String ist ein Object in Java, also fällt es in diese Kategorie von Vergleichsregeln.

  • Dies hat die Frage nicht beantwortet und ist irgendwie irreführend. Sie können == nicht zuverlässig für eine Zeichenfolge ausführen

    – CodeMonkey

    9. April 2018 um 20:54 Uhr

1354930cookie-checkIst die Methode assertEquals von Java zuverlässig?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy