Ik heb de ==
operator gebruikt in mijn programma om al mijn strings te vergelijken.
Ik kwam echter een bug tegen, veranderde een van hen in .equals()
in plaats daarvan, en het loste de bug op.
Is ==
slecht? Wanneer moet het wel en wanneer moet het niet gebruikt worden? Wat is het verschil?
==
test voor referentie gelijkheid (of ze hetzelfde object zijn).
.equals()
controleert de gelijkheid van waarden (of ze logisch "gelijk" zijn).
Objects.equals() controleert op null
voordat je .equals()
aanroept, zodat je dat niet hoeft te doen (beschikbaar vanaf JDK7, ook beschikbaar in Guava).
String.contentEquals() vergelijkt de inhoud van de String
met de inhoud van een CharSequence
(beschikbaar sinds Java 1.5).
Bijgevolg, als je wilt testen of twee strings dezelfde waarde hebben, zul je waarschijnlijk Objects.equals()
willen gebruiken.
// 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
Je wilt bijna altijd Objects.equals()
gebruiken. In de zeldzame situatie waarin je weet dat je te maken hebt met geïnterneerde strings, kan je ==
gebruiken.
Uit JLS 3.10.5. String Literals:
Bovendien verwijst een string literal altijd naar dezelfde instantie van de klasse
String
. Dit komt omdat string literals - of, meer in het algemeen, strings die de waarden zijn van constante expressies (§15.28) - worden "interned" zodat ze unieke instanties delen, met behulp van de methodeString.intern
.
Soortgelijke voorbeelden zijn ook te vinden in JLS 3.10.5-1.
Ja, ==
is slecht voor het vergelijken van Strings (alle objecten eigenlijk, tenzij je weet dat ze'canoniek zijn). ==
vergelijkt alleen object referenties. .equals()
test voor gelijkheid. Voor Strings zullen ze vaak gelijk zijn, maar zoals je hebt ontdekt, is dat niet altijd gegarandeerd.
==
vergelijkt object referenties in Java, en dat is geen uitzondering voor String
objecten.
Voor het vergelijken van de werkelijke inhoud van objecten (inclusief String
), moet men de equals
methode gebruiken.
Als een vergelijking van twee String
objecten met ==
true
blijkt te zijn, dan komt dat omdat de String
objecten geïnterned zijn, en de Java Virtual Machine meerdere verwijzingen naar dezelfde instantie van String
laat wijzen. Men moet niet verwachten dat het vergelijken van een String
object met dezelfde inhoud als een ander String
object met behulp van ==
als true
zal evalueren.