Cohérence dans la langue. Avoir un opérateur qui agit différemment peut être surprenant pour le programmeur. Java n'autorise pas les utilisateurs à surcharger les opérateurs - par conséquent, l'égalité de référence est la seule signification raisonnable ==
entre les objets.
Dans Java:
- Entre les types numériques,
==
compare l'égalité numérique
- Entre types booléens,
==
compare l'égalité booléenne
- Entre les objets,
==
compare l'identité de référence
- Utiliser
.equals(Object o)
pour comparer les valeurs
C'est ça. Règle simple et simple pour identifier ce que vous voulez. Tout cela est traité dans la section 15.21 du JLS . Il comprend trois sous-sections faciles à comprendre, à mettre en œuvre et à raisonner.
Une fois que vous autorisez la surcharge de==
, le comportement exact n'est pas quelque chose que vous pouvez regarder vers le JLS et mettre le doigt sur un élément spécifique et dire "c'est comme ça que ça marche", le code peut devenir difficile à raisonner. Le comportement exact de ==
peut être surprenant pour un utilisateur. Chaque fois que vous le voyez, vous devez revenir en arrière et vérifier ce que cela signifie réellement.
Comme Java ne permet pas de surcharger les opérateurs, il est nécessaire de disposer d’un test d’égalité des valeurs que vous pouvez remplacer par la définition de base. Ainsi, il a été mandaté par ces choix de conception. ==
en Java, teste numeric pour les types numériques, égalité booléenne pour les types booléens et égalité de référence pour tout le reste (ce qui peut se substituer .equals(Object o)
à tout ce qu'ils veulent pour l'égalité des valeurs).
Ce n’est pas une question de "existe-t-il un cas d’utilisation pour une conséquence particulière de cette décision de conception" mais plutôt "il s’agit d’une décision de conception visant à faciliter ces autres choses, c’est une conséquence de celle-ci".
String interning en est un exemple. Selon JLS 3.10.5 , tous les littéraux de chaîne sont internés. Les autres chaînes sont internées si on y invoque .intern()
. Cela "foo" == "foo"
est vrai, est une conséquence des décisions de conception prises pour minimiser l’empreinte mémoire des littéraux de chaîne. Au-delà, l’internalisation des chaînes est quelque chose qui, au niveau de la JVM, a un peu de visibilité sur l’utilisateur, mais dans la très grande majorité des cas, ne devrait pas concerner le programmeur (et les cas d’utilisation pour quelque chose qui figurait en haut de la liste pour les concepteurs lorsqu’on envisage cette fonctionnalité).
Les gens vont le souligner +
et +=
sont surchargés pour String. Cependant, ce n'est ni ici ni là-bas. Cela reste le cas que si ==
a une signification d'égalité de valeur pour String (et uniquement String), il faudrait une méthode différente (qui n'existe que dans String) pour l'égalité de référence. De plus, cela compliquerait inutilement les méthodes qui prennent Object et s’attendent ==
à ce qu’elles se comportent d’une manière et .equals()
d’une autre, obligeant les utilisateurs à casse toutes ces méthodes pour String.
Le contrat cohérent pour ==
on Objects est qu'il ne s'agit que d'égalité de référence et qu'il .equals(Object o)
existe pour tous les objets qui doivent tester l'égalité de valeur. Compliquer cela complique beaucoup trop de choses.
==
se trouvent l' égalité d'objet et l'eq
égalité de référence ( ofps.oreilly.com/titles/9780596155957/… ).