Ich habe den Operator ==
in meinem Programm verwendet, um alle meine Zeichenketten zu vergleichen.
Ich bin jedoch auf einen Fehler gestoßen und habe einen der Operatoren in .equals()
geändert, wodurch der Fehler behoben wurde.
Ist ==
schlecht? Wann sollte es verwendet werden und wann nicht? Was ist der Unterschied?
==` testet auf Referenzgleichheit (ob es sich um dasselbe Objekt handelt).
.equals()
prüft auf Wertgleichheit (ob sie logisch "gleich" sind).
Objects.equals() prüft vor dem Aufruf von .equals()
auf null
, damit Sie das nicht tun müssen (verfügbar ab JDK7, auch in Guava).
String.contentEquals() vergleicht den Inhalt von String
mit dem Inhalt einer beliebigen CharSequence
(verfügbar seit Java 1.5).
Wenn Sie also testen wollen, ob zwei Strings den gleichen Wert haben, werden Sie wahrscheinlich Objects.equals()
verwenden wollen.
// These two have the same value
new String("test").equals("test") // --> true
// ... but they are not the same object
new String("test") == "test" // --> false
// ... neither are these
new String("test") == new String("test") // --> false
// ... but these are because literals are interned by
// the compiler and thus refer to the same object
"test" == "test" // --> true
// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true
// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true
Sie wollen fast immer Objects.equals()
verwenden. In der seltenen Situation, in der Sie wissen, dass Sie es mit [internierten] (https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#intern--) Strings zu tun haben, können Sie ==
verwenden.
Aus JLS 3.10.5. String Literals:
Außerdem bezieht sich ein Stringliteral immer auf die gleiche Instanz der Klasse
String
. Das liegt daran, dass Stringliterale - oder, allgemeiner, Strings, die die Werte von konstanten Ausdrücken sind (§15.28) - "interniert" werden, um eindeutige Instanzen zu teilen, indem die MethodeString.intern
verwendet wird.
Ähnliche Beispiele finden sich auch in JLS 3.10.5-1.
Ja, ==
ist schlecht für den Vergleich von Strings (eigentlich für alle Objekte, es sei denn, Sie wissen, dass sie kanonisch sind). ==
vergleicht nur Objektreferenzen. .equals()
testet auf Gleichheit. Bei Strings sind sie oft gleich, aber wie Sie festgestellt haben, ist das nicht immer garantiert.
==
vergleicht Objektreferenzen in Java, und das ist keine Ausnahme für String
-Objekte.
Für den Vergleich des tatsächlichen Inhalts von Objekten (einschließlich String
) muss man die Methode equals
verwenden.
Wenn ein Vergleich zweier String'-Objekte mit
==als
wahrherauskommt, liegt das daran, dass die
String'-Objekte interniert wurden und die Java Virtual Machine mehrere Referenzen auf dieselbe Instanz von String
zeigen lässt. Man sollte nicht erwarten, dass der Vergleich eines String'-Objekts, das denselben Inhalt wie ein anderes
String'-Objekt hat, mit ==
als wahr
ausgewertet wird.