Finora ho usato l'operatore ==
nel mio programma per confrontare tutte le mie stringhe.
Tuttavia, mi sono imbattuto in un bug, ho cambiato uno di loro in .equals()
invece, e ha risolto il bug.
L'operatore ==
è un male? Quando dovrebbe e non dovrebbe essere usato? Qual è la differenza?
==
verifica l'uguaglianza dei riferimenti (se sono lo stesso oggetto).
.equals()
verifica l'uguaglianza dei valori (se sono logicamente "uguali").
Objects.equals() controlla la presenza di null
prima di chiamare .equals()
in modo da non doverlo fare (disponibile da JDK7, disponibile anche in Guava).
String.contentEquals() confronta il contenuto della Stringa
con il contenuto di qualsiasi CharSequence
(disponibile da Java 1.5).
Di conseguenza, se volete testare se due stringhe hanno lo stesso valore, probabilmente vorrete usare 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
Volete quasi sempre usare Objects.equals()
. Nella rara situazione in cui sapete che avete a che fare con stringhe interned, potete *usare ==
.
Da JLS 3.10.5. Letteratura delle stringhe:
Inoltre, un letterale di stringa si riferisce sempre alla stessa istanza della classe String
. Questo perché i letterali di stringa - o, più in generale, le stringhe che sono i valori delle espressioni costanti (§15.28) - sono "internati" in modo da condividere istanze uniche, utilizzando il metodo String.intern
.
Esempi simili si trovano anche in JLS 3.10.5-1.
Sì, ==
non va bene per confrontare le stringhe (qualsiasi oggetto in realtà, a meno che tu non sappia che sono canonici). ==
confronta solo i riferimenti agli oggetti. .equals()
verifica l'uguaglianza. Per le stringhe, spesso saranno uguali, ma come hai scoperto, questo non è sempre garantito.
==
confronta i riferimenti agli oggetti in Java, e questo non fa eccezione per gli oggetti String
.
Per confrontare il contenuto effettivo degli oggetti (inclusa la Stringa
), si deve usare il metodo equals
.
Se un confronto tra due oggetti Stringa
usando ==
risulta essere vero
, è perché gli oggetti Stringa
sono stati internati, e la Java Virtual Machine sta facendo puntare più riferimenti alla stessa istanza di Stringa
. Non ci si dovrebbe aspettare che il confronto di un oggetto Stringa
che contiene lo stesso contenuto di un altro oggetto Stringa
usando ==
valuti come true
.