assertEquals
usa el equals
método de comparación. Hay una afirmación diferente assertSame
, que utiliza el ==
operador.
Para comprender por ==
qué no debe usarse con cadenas, debe comprender lo que ==
hace: hace una verificación de identidad. Es decir, a == b
comprueba para ver si a
y se b
refieren al mismo objeto . Está integrado en el lenguaje, y su comportamiento no puede ser cambiado por diferentes clases. El equals
método, por otro lado, puede ser anulado por clases. Si bien su comportamiento predeterminado (en la Object
clase) es hacer una verificación de identidad utilizando el ==
operador, muchas clases, incluso String
, la anulan para hacer una verificación de "equivalencia". En el caso de String
, en lugar de verificar si a
y hacer b
referencia al mismo objeto,a.equals(b)
comprueba si los objetos a los que se refieren son cadenas que contienen exactamente los mismos caracteres.
Tiempo de analogía: imagine que cada String
objeto es un pedazo de papel con algo escrito en él. Digamos que tengo dos pedazos de papel con "Foo" escrito en ellos, y otro con "Bar" escrito en él. Si tomo los dos primeros trozos de papel y los uso ==
para compararlos, se devolverá false
porque esencialmente se pregunta "¿son estos el mismo trozo de papel?". Ni siquiera necesita mirar lo que está escrito en el papel. El hecho de que le esté dando dos hojas de papel (en lugar de la misma dos veces) significa que volverá false
. equals
Sin embargo, si lo uso , el equals
método leerá las dos hojas de papel y verá que dicen lo mismo ("Foo"), y así volverá true
.
La parte que se confunde con las cadenas es que Java tiene un concepto de cadenas "internas", y esto (efectivamente) se realiza automáticamente en cualquier literal de cadena en su código. Esto significa que si tiene dos literales de cadena equivalentes en su código (incluso si están en clases diferentes), ambos se referirán al mismo String
objeto. Esto hace que el ==
operador regrese con true
más frecuencia de lo que cabría esperar.