Jusqu'à présent, j'ai utilisé l'opérateur ==
dans mon programme pour comparer toutes mes chaînes de caractères.
Cependant, j'ai rencontré un problème, j'ai changé l'un d'entre eux en .equals()
à la place, et cela a corrigé le problème.
Est-ce que ==
est mauvais ? Quand faut-il l'utiliser et quand ne faut-il pas l'utiliser ? Quelle est la différence ?
==
teste l'égalité des références (si elles sont le même objet).
.equals()
teste l'égalité des valeurs (s'ils sont logiquement "égaux").
Objects.equals() vérifie la présence de null
avant d'appeler .equals()
pour vous éviter de le faire (disponible à partir du JDK7, également disponible dans Guava).
String.contentEquals() compare le contenu de la String
avec le contenu de n'importe quelle CharSequence
(disponible depuis Java 1.5).
Par conséquent, si vous voulez tester si deux chaînes de caractères ont la même valeur, vous voudrez probablement utiliser Objects.equals()
.
// These two have the same value
new String("test").equals("test") // --> true
// ... but they are not the same object
new String("test") == "test" // --> false
// ... neither are these
new String("test") == new String("test") // --> false
// ... but these are because literals are interned by
// the compiler and thus refer to the same object
"test" == "test" // --> true
// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true
// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true
Vous voulez presque toujours utiliser Objects.equals()
. Dans le cas rare où vous savez que vous avez affaire à des chaînes de caractères internées, vous pouvez utiliser ==
.
Extrait de JLS 3.10.5. String Literals :
De plus, un littéral de chaîne de caractères fait toujours référence à la même instance de la classe
String
. Cela est dû au fait que les chaînes littérales - ou, plus généralement, les chaînes qui sont les valeurs d'expressions constantes (§15.28) - sont "internées" de manière à partager des instances uniques, en utilisant la méthodeString.intern
.
Des exemples similaires se trouvent également dans JLS 3.10.5-1.
Oui, ==
est mauvais pour comparer des chaînes de caractères (ou tout autre objet, à moins que vous ne sachiez qu'ils sont canoniques). ==
ne fait que comparer des références d'objets. .equals()
teste l'égalité. Pour les chaînes de caractères, elles seront souvent identiques, mais comme vous l'avez découvert, ce n'est pas toujours garanti.
==
compare les références d'objets en Java, et cela ne fait pas exception pour les objets String
.
Pour comparer le contenu réel des objets (y compris les String
), il faut utiliser la méthode equals
.
Si la comparaison de deux objets String
à l'aide de la méthode ==
s'avère être vrai
, c'est parce que les objets String
ont été internés, et que la machine virtuelle Java fait pointer plusieurs références vers la même instance de String
. Il ne faut pas s'attendre à ce que la comparaison d'un objet String
contenant le même contenu qu'un autre objet String
en utilisant ==
soit évaluée comme true
.