Wenn "" == s ist falsch aber "" .equals (s) ist wahr
BEARBEITEN
Vielen Dank für die prompte Antworten. Bitte sehen, was die eigentliche Frage ist. Ich habe es Fett dieser Zeit.
Ich verstehe den Unterschied zwischen == und .entspricht. So, das ist nicht meine Frage (ich habe tatsächlich einige zusätzliche Kontext für das)
Ich bin der Durchführung der Validierung unten für leere Saiten:
if( "" == value ) {
//is empty string
}
In der Vergangenheit beim abrufen der Werte aus der db oder Deserialisieren von Objekten von einem anderen Knoten, dieser test fehlgeschlagenweil die beiden string-Instanzen waren in der Tat andere Objekt verweist, wenn auch Sie enthalten die gleichen Daten.
So das Update für diese Situationen wurde
if( "".equals( value ) ) {
//which returns true for all the empty strings
}
Ich bin gut mit, dass. Das ist klar zu verstehen.
Heute passierte dies wieder, aber es verwirrt mich, weil in dieser Zeit der Anwendung ist eine sehr kleine standalone-Anwendungder nicht Netzwerk überhauptso dass keine neue string aus der Datenbank abgerufen, noch deserizalized von einem anderen Knoten.
Also die Frage ist:
Unter denen ANDEREN Umstände:
"" == value //yields false
und
"".equals( value ) //yields true
Für eine lokale standalone-Anwendung?
Ich bin mir ziemlich sicher, dass new String() ist nicht im code verwendet.
Und die einzige Möglichkeit, eine string-Referenz werden könnte "" ist, weil es wird zugewiesen "" direkt in den code (oder das, was ich dachte), wie in:
String a = "";
String b = a;
assert "" == b ; //this is true
Irgendwie (nach dem Lesen der code mehr habe ich eine Ahnung) zwei verschiedene leere string-Objekt-Referenzen erstellt wurden, würde ich gerne wissen, wie
Mehr in der Linie der jjnguys Antwort:
Byte!
EDIT: Fazit
Habe ich den Grund gefunden.
Nach jjnguy Vorschlag, den ich war in der Lage zu schauen mit anderen Augen auf den code.
Schuldig-Methode: die Klasse StringBuilder.toString()
Ein neues String-Objekt zugewiesen und initialisiert, enthalten die Zeichenfolge, die derzeit vertreten durch das Objekt.
Doh!...
StringBuilder b = new StringBuilder("h");
b.deleteCharAt( 0 );
System.out.println( "" == b.toString() ); //prints false
Rätsel gelöst.
Den code verwendet StringBuilder umgehen mit einer stetig wachsenden string. Es stellt sich heraus, dass irgendwann jemand:
public void someAction( String string ) {
if( "" == string ) {
return;
}
deleteBankAccount( string );
}
und verwenden
someAction( myBuilder.toString() ); //bug introduced.
p.s. Ich lese auch viel CodingHorror in letzter Zeit? Oder warum fühle ich das Bedürfnis, fügen Sie einige lustige Tier Bilder hier?
InformationsquelleAutor der Frage OscarRyz | 2009-07-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sowas dazu führen würde, dass
s == s2
um zu false ausgewertet.Viel code, Schweller neu erstellen
Strings
aussetzt, ohne den Anruf zunew String()
.InformationsquelleAutor der Antwort jjnguy
und
jeder Zeit den Wert der Variablen
value
wurde nicht interniert. Dies ist dann der Fall, wenn der Wert zur Laufzeit berechnet wird. Finden Sie die JLS Abschnitt 3.10.5 String Literals zum Beispiel code zur Veranschaulichung:InformationsquelleAutor der Antwort Bill the Lizard
Wenn Sie können, schnappen Sie sich einen halten, der das Buch Java Teilnehmer von Joshua Bloch und Neal Gafter, und betrachten puzzle 13, "Animal Farm"... er hat auch tolle Ratschläge zu diesem Thema. Ich werde kopieren einige relevante text:
"Sie wissen vielleicht, dass compile-Zeit-Konstanten des Typs
String
sind interniert [JLS 15.28]. In anderen Worten: alle zwei Konstante Ausdrücke TypString
, benennen die gleiche Zeichenfolge vertreten durch identische Objekt-Referenzen... Ihr code sollte nur selten, wenn überhaupt, hängt von dem Praktikum von string-Konstanten. Praktikum entworfen wurde, allein zu reduzieren, den Speicherbedarf der virtuellen Maschine, nicht wie ein tool für Programmierer... Beim Vergleich von Objekt-Referenzen, sollten Sie verwenden Sie dieequals
Methode den Vorzug vor der==
Betreiberes sei denn, Sie brauchen, um zu vergleichen, Objekt-Identität, vielmehr als Wert."Dass die aus den obigen Hinweis, den ich erwähnt... Seiten 30 - 31 in meinem Buch.
InformationsquelleAutor der Antwort Tom
Würden Sie erwarten
"abcde".substring(1,2)
und"zbcdefgh".substring(1,2)
ergeben die gleichen String-Objekt?Beide Ausbeute "gleich" sub-strings extrahiert aus zwei verschiedenen Saiten, aber es scheint durchaus sinnvoll, dass die tehy sind verschiedene Objekte, also == Sie sieht so anders aus.
Nun berücksichtigen, wenn der Teilstring hat die Länge 0,
substring(1, 1)
. Es ergibt sich eine null-Zeichenfolge der Länge, aber es ist nicht verwunderlich, dass die"abcde".substring(1,1)
ist ein anderes Objekt von"zbcdefgh".substring(1,2)
und damit mindestens einer von Ihnen ist ein anderes Objekt "".InformationsquelleAutor der Antwort djna
Wie ich es verstehe, während der Kompilierung der Java-code zu bytecode oder während des Laufenden Programms gleichen strings referenziert das gleiche Objekt in den meisten Fällen um Speicher zu sparen. Also manchmal sind Sie Weg mit == vergleichen von strings. Aber dies ist eine compiler-Optimierung, die Sie sich nicht darauf verlassen können.
Aber dann passiert es manchmal, dass der compiler entscheidet, dies nicht tun-Optimierung oder gibt es keine Möglichkeit für das Programm zu sehen, dass die strings sind die gleichen, und aus der plötzlich der check fehlschlägt, da Sie sich auf einige zugrunde liegende Optimierung voodoo, hängt von der Implementierung der jvm, die Sie benutzen und so weiter.
Also mit equals immer das gute zu tun. Für leere Zeichenfolgen es gibt andere Möglichkeiten, wie der Vergleich mit der Länge == 0 oder, wenn Sie kümmern sich nicht um die rückwärts-Kompatibilität es ist eine Zeichenfolge.empty().
InformationsquelleAutor der Antwort Janusz
Sollten Sie versuchen, unter Berücksichtigung
String.length() == 0
.InformationsquelleAutor der Antwort Paul Sonier
Überprüfen Sie diesen Hinweis: http://mindprod.com/jgloss/string.html#COMPARISON an der ausgezeichneten Kanadier Produkte Java & Internet-Glossar. Lohnt sich ein Lesezeichen.
InformationsquelleAutor der Antwort artlung
Den javadoc für
String.intern()
hat einige gute Kommentare auf==
vs..equals()
.Die Dokumentation stellt außerdem klar, dass jedes string-literal ist
intern
'd....InformationsquelleAutor der Antwort Alex B
Wenn Sie google-code-Suche, finden Sie viele Orte, wo die Menschen die gleiche Fehlermeldung: google file:.java \=\=\ \"\" natürlich kann das eine richtige idiom in sorgfältig kontrollierten Umständen, in der Regel aber, es ist nur ein bug.
InformationsquelleAutor der Antwort Trevor Harrison
Warum nicht:
Sollten Sie verwenden
equals()
weil==
für Objekte vergleicht Referenzen, D. H., Sie sind das gleiche Objekt. Während bei der Kompilierung von Java findet identische strings und macht Sie zu teilen, die die gleiche Referenz (Strings sind immutable), zur Laufzeit ist es einfach zu erstellen Sie leere Zeichenfolgen, die verschiedenen Verweise, wo == fehlschlägt, für Ihre typischen Absichtequals()
.InformationsquelleAutor der Antwort JeeBee