J'apprends Kotlin, avec un arrière-plan C++ et Java. Je m'attendais à ce que les éléments suivants impriment true
et non false
. Je sais que ==
correspond à equals
. L'implémentation par défaut de equals
ne compare-t-elle pas chaque membre, c'est-à-dire firstName
et lastName
? Si tel est le cas, ne verrait-il pas les valeurs de chaîne comme égales (puisque ==
correspond à equal
encore)? Apparemment, il y a quelque chose lié à l'égalité contre l'identité que je n'ai pas encore bien compris dans Kotlin.
class MyPerson(val firstName: String, val lastName: String)
fun main(args: Array<String>) {
println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker"))
}
L'implémentation par défaut equals
que vous décrivez n'existe que pour les classes de données. Pas pour les classes régulières où l'implémentation est héritée de Object
et rend juste l'objet égal à lui-même.
Java
En Java, l’implémentation par défaut de equals
compare la variable référence , qui correspond à ce que ==
always fait:
La méthode
equals
pour la classeObject
implémente la relation d'équivalence La plus discriminante possible sur les objets; c’est-à-dire que pour toute valeur de référence x et y non nulle, cette méthode retournetrue
si et seulement si x et y font référence au même objet (x == y
a la valeurtrue
).
Nous appelons cela " référentiel égalité".
Kotlin
Dans Kotlin, ==
est compilé en equals
, alors que ===
est l'équivalent du ==
de Java.
Chaque fois que nous voulons plutôt structurelle que référentielle égalité, nous pouvons redéfinir equals
, qui est jamais fait par défaut pour les classes normales, suggéré. Dans Kotlin, nous pouvons utiliser data class
, pour lequel le compilateur crée automatiquement une implémentation basée sur les propriétés du constructeur (read here ).
N'oubliez pas de toujours surcharger hashCode
si vous écrasez equals
(et vice versa) manuellement et que vous vous en tenez aux très stricts contrats des deux méthodes. Les implémentations générées par le compilateur de Kotlin satisfont au contrat.
== pour l'égalité
En Java, vous pouvez utiliser == pour comparer les types de primitive et de référence. Si appliqué aux types primitifs, Java == compare les valeurs, tandis que == sur les types de référence compare les références. Ainsi, à Java, il existe une pratique bien connue consistant à toujours appeler les égaux et un problème bien connu consistant à oublier de le faire.
En Kotlin, == est le moyen par défaut de comparer deux objets: il compare leurs valeurs en appelant égaux sous le capot. Ainsi, si égal est remplacé dans votre classe, vous pouvez comparer ses instances en toute sécurité en utilisant ==. Pour comparer les références, vous pouvez utiliser l'opérateur ===, qui fonctionne exactement de la même manière que == en Java.
class MyPerson(val firstName: String, val lastName: String){
override fun equals(other: Any?): Boolean {
if (other == null || other !is MyPerson) return false
return firstName == other.firstName && lastName == other.lastName
}
}
fun main(args: Array<String>) {
println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker")) // print "true"
}
Dans votre cas, MyPerson
est un data class
qui génère automatiquement les implémentations de méthodes universelles (toString
, equals
et hashCode
).