He estado usando el operador ==
en mi programa para comparar todas mis cadenas hasta ahora.
Sin embargo, me encontré con un error, cambié uno de ellos en .equals()
en su lugar, y arregló el error.
¿Es malo ==
? ¿Cuándo debe y no debe usarse? ¿Cuál es la diferencia?
==
comprueba la igualdad de referencias (si son el mismo objeto).
.equals()
comprueba la igualdad de valores (si son lógicamente "iguales").
Objects.equals() comprueba la existencia de null
antes de llamar a .equals()
para no tener que hacerlo (disponible a partir de JDK7, también disponible en Guava).
String.contentEquals() compara el contenido del String
con el contenido de cualquier CharSequence
(disponible desde Java 1.5).
Por lo tanto, si quiere comprobar si dos cadenas tienen el mismo valor, probablemente querrá utilizar 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
Casi siempre querrás usar Objects.equals()
. En la rara situación en la que sabes que estás tratando con cadenas internadas, puedes usar ==
.
De JLS 3.10.5. String Literals:
Además, un literal de cadena siempre se refiere a la misma instancia de la clase
String
. Esto se debe a que los literales de cadena - o, más generalmente, las cadenas que son los valores de expresiones constantes (§15.28) - se "internan" para compartir instancias únicas, usando el métodoString.intern
.
También se pueden encontrar ejemplos similares en JLS 3.10.5-1.
Sí, ==
es malo para comparar cadenas (cualquier objeto en realidad, a menos que sepas que son canónicos). ==
sólo compara referencias a objetos. El comando .equals()
comprueba la igualdad. En el caso de las cadenas, a menudo serán iguales, pero, como has descubierto, eso no está garantizado siempre.
==
compara las referencias de los objetos en Java, y eso no es una excepción para los objetos String
.
Para comparar el contenido real de los objetos (incluyendo String
), se debe utilizar el método equals
.
Si una comparación de dos objetos String
usando ==
resulta ser true
, es porque los objetos String
fueron internados, y la máquina virtual de Java está teniendo múltiples referencias que apuntan a la misma instancia de String
. No se debe esperar que la comparación de un objeto String
que contiene el mismo contenido que otro objeto String
utilizando ==
se evalúe como true
.