ProgrammationDéveloppeur Backend

Expliquez le fonctionnement des opérateurs '==' et '===' en Kotlin. Quelle est la spécificité de la comparaison des objets et des types significatifs, que se passe-t-il en arrière-plan lors de la comparaison et comment éviter l'erreur fréquente d'équivalence ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

En Kotlin, il existe deux opérateurs de comparaison :

  • ==comparaison structurelle (équivalent à .equals()). Cela vérifie le contenu : a == b appelle a?.equals(b) ?: (b == null).
  • ===comparaison par référence. Vérifie si les deux variables pointent vers le même objet : a === b est équivalent à Java a == b pour les objets.

Pour les types primitifs (par exemple, Int) : == et === peuvent se comporter de la même manière en raison de l'autoboxing, mais en général, il faut utiliser ==.

Exemple de code

val a = "Kotlin" val b = "Kotlin" val c = a println(a == b) // true (comparaison de contenu) println(a === b) // false (références différentes — les chaînes sont internées selon le compilateur) println(a === c) // true (même objet)

Question piégeuse.

Quelle est la différence entre a.equals(b) et a == b en Kotlin ?

Certains affirment qu'il n'y a pas de différence, cependant, si a est nullable, l'appel a.equals(b) déclenchera un NullPointerException, tandis que a == b est sécurisé et renverra true si les deux sont null, ou false si l'un d'eux est null.

Exemple :

val a: String? = null val b: String? = null println(a == b) // true println(a?.equals(b)) // null (et non true, mais pas un crash) println(a.equals(b)) // NullPointerException

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet.


Histoire

Dans un grand projet, des chaînes nullable étaient activement comparées via a.equals(b), sans soupçonner que lors de a == null, l'application se plantait. Le bug se produisait assez rarement, mais entraînait des pannes fatales en production — corrigé en remplaçant par a == b.


Histoire

En comparant des objets via ===, une comparaison de contenu était attendue, mais === vérifie l'identité des objets — il est apparu que deux chaînes différentes avec le même contenu ne sont pas égales par ===, ce qui a cassé la logique de mise en cache des données.


Histoire

En travaillant avec des valeurs Int encapsulées (par exemple, provenant de collections), les développeurs les comparaient via === et obtenaient des résultats inattendus car les instances d'objet de différents nombres ne sont pas nécessairement internées comme des primitifs. Cela a conduit à un comportement incorrect lors de la manipulation de collections d'objets.