Olen käyttänyt ohjelmassani ==
-operaattoria vertaillakseni kaikkia merkkijonojani tähän mennessä.
Törmäsin kuitenkin virheeseen, muutin yhden niistä .equals()
:ksi sen sijaan, ja se korjasi virheen.
Onko ==
huono? Milloin sitä pitäisi ja milloin ei pitäisi käyttää? Mitä eroa sillä on?
==
testaa viittausten yhdenvertaisuuden (ovatko ne sama objekti).
.equals()
testaa arvojen yhdenvertaisuuden (ovatko ne loogisesti "yhtä").
Objects.equals() tarkistaa null
:n varalta ennen .equals()
:n kutsumista, jotta sinun ei tarvitse tehdä sitä (käytettävissä JDK7:stä lähtien, käytettävissä myös Guavassa).
String.contentEquals()) vertaa String
:n sisältöä minkä tahansa CharSequence
:n sisältöön (käytettävissä Java 1.5:stä lähtien).
Jos siis haluat testata, onko kahdella merkkijonolla sama arvo, haluat todennäköisesti käyttää Objects.equals()
.
// 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
Haluat lähes aina käyttää Objects.equals()
. Siinä harvinaisessa tilanteessa, jossa tiedät, että olet tekemisissä [sisäistettyjen] (https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#intern--) merkkijonojen kanssa, voit voi käyttää ==
.
Kohdasta JLS 3.10.5. String Literals:
Lisäksi merkkijono literaali viittaa aina luokan
String
samaan instanssiin. Tämä johtuu siitä, että merkkijonolitteraalit - tai yleisemmin merkkijonot, jotka ovat vakiolausekkeiden arvoja (§15.28) - "sisäistetään" siten, että ne jakavat ainutlaatuisia instansseja metodinString.intern
avulla.
Vastaavia esimerkkejä löytyy myös JLS 3.10.5-1.
Kyllä, ==
on huono merkkijonojen (tai oikeastaan minkä tahansa objektin, ellet tiedä niiden olevan kanonisia) vertailussa. ==
vertaa vain objektiviittauksia. .equals()
testaa yhdenvertaisuuden. Stringien osalta ne ovat usein samoja, mutta kuten olet huomannut, se ei ole aina taattua.
==
vertaa objektiviittauksia Javassa, eikä se ole poikkeus String
-objektien kohdalla.
Objektien (mukaan lukien String
) todellisen sisällön vertailuun on käytettävä equals
-metodia.
Jos kahden String
-objektin vertailu ==
-menetelmällä osoittautuu todeksi
, se johtuu siitä, että String
-objektit on sisäistetty, ja Java-virtuaalikone antaa useiden viittausten osoittaa samaan String
-olioon. Ei pitäisi odottaa, että yhden String
-objektin, joka sisältää saman sisällön kuin toinen String
-objekti, vertaaminen ==
:n avulla arvioitaisiin todeksi
.