ProgramaciónDesarrollador Backend

Explique el funcionamiento de los operadores '==' y '===' en Kotlin. ¿Cuál es la especificidad de la comparación de objetos y tipos significativos, qué sucede en el fondo al comparar, y cómo evitar el error común de equivalencia?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

En Kotlin hay dos operadores para la comparación:

  • ==comparación estructural (equivalente a .equals()). Comprueba el contenido: a == b invoca a?.equals(b) ?: (b == null).
  • ===comparación de referencia. Verifica si ambas variables apuntan al mismo objeto: a === b es equivalente a Java a == b para objetos.

Para tipos primitivos (por ejemplo, Int): == y === pueden comportarse igual debido al autoboxing, pero en general se debe usar ==.

Ejemplo de código

val a = "Kotlin" val b = "Kotlin" val c = a println(a == b) // true (comparación de contenido) println(a === b) // false (referencias diferentes — cadenas internadas depende del compilador) println(a === c) // true (el mismo objeto)

Pregunta trampa.

¿Cuál es la diferencia entre a.equals(b) y a == b en Kotlin?

Algunos afirman que no hay diferencia, sin embargo, si a es nullable, la llamada a a.equals(b) lanzará NullPointerException, mientras que a == b es seguro y retornará true si ambos son null, o false si solo uno de ellos es null.

Ejemplo:

val a: String? = null val b: String? = null println(a == b) // true println(a?.equals(b)) // null (y no true, pero no una excepción) println(a.equals(b)) // NullPointerException

Ejemplos de errores reales por desconocer los matices del tema.


Historia

En un gran proyecto, se comparaban activamente cadenas nullable a través de a.equals(b), sin sospechar que al tener a == null la aplicación fallaba. El error se repetía bastante raro, pero causaba fallos fatales en producción — se corrigió cambiando a a == b.


Historia

Al comparar objetos mediante === se esperaba una comparación de contenido, pero === verifica la identidad de los objetos — se descubrió que dos cadenas diferentes con el mismo contenido no son iguales a través de ===, lo que rompió la lógica de caché de datos.


Historia

Al trabajar con valores Int encapsulados (por ejemplo, de colecciones), los desarrolladores los comparaban con === y obtenían resultados inesperados debido a que las instancias de objeto de diferentes números no se internan necesariamente como primitivos. Esto llevaba a un comportamiento incorrecto al trabajar con colecciones de objetos.