Je sais que cela ==
pose quelques problèmes lors de la comparaison de deux Strings
. Il paraît queString.equals()
soit une meilleure approche. Eh bien, je fais des tests JUnit et mon inclination est d'utiliser assertEquals(str1, str2)
. Est-ce un moyen fiable d'affirmer que deux chaînes contiennent le même contenu? J'utiliserais assertTrue(str1.equals(str2))
, mais vous n'obtenez pas l'avantage de voir quelles sont les valeurs attendues et réelles en cas d'échec.
Sur une note connexe, quelqu'un a-t-il un lien vers une page ou un fil qui explique clairement les problèmes str1 == str2
?
Réponses:
Vous devez toujours utiliser
.equals()
lors de la comparaisonStrings
en Java.JUnit appelle la
.equals()
méthode pour déterminer l'égalité dans la méthodeassertEquals(Object o1, Object o2)
.Donc, vous êtes certainement en sécurité
assertEquals(string1, string2)
. (Parce queString
s sontObject
s)Voici un lien vers une grande question Stackoverflow concernant certaines des différences entre
==
et.equals()
.la source
assertEquals
utilise laequals
méthode pour la comparaison. Il existe une assertion différenteassertSame
, qui utilise l'==
opérateur.Pour comprendre pourquoi
==
ne devrait pas être utilisé avec des chaînes, vous devez comprendre ce qui==
fait: il fait un contrôle d'identité. Autrement dit,a == b
vérifie sia
et faitb
référence au même objet . Il est intégré au langage et son comportement ne peut pas être modifié par différentes classes. Laequals
méthode, en revanche, peut être remplacée par des classes. Bien que son comportement par défaut (dans laObject
classe) consiste à effectuer un contrôle d'identité à l'aide de l'==
opérateur, de nombreuses classes, y comprisString
, le remplacent pour effectuer à la place un contrôle "d'équivalence". Dans le cas deString
, au lieu de vérifier si vérifie pour voir si les objets auxquels ils se réfèrent sont les deux chaînes qui contiennent exactement les mêmes caractères.a
etb
faire référence au même objet,a.equals(b)
Temps d'analogie: imaginez que chaque
String
objet est un morceau de papier avec quelque chose d'écrit dessus. Disons que j'ai deux morceaux de papier avec "Foo" écrits dessus, et un autre avec "Bar" écrit dessus. Si je prends les deux premiers morceaux de papier et que je les utilise==
pour les comparer, cela reviendrafalse
car il s'agit essentiellement de demander "S'agit-il du même morceau de papier?". Il n'a même pas besoin de regarder ce qui est écrit sur le papier. Le fait que je lui donne deux morceaux de papier (plutôt que le même deux fois) signifie qu'il reviendrafalse
. Si j'utiliseequals
, cependant, laequals
méthode lira les deux morceaux de papier et verra qu'ils disent la même chose ("Foo"), et donc ça reviendratrue
.Le bit qui devient confus avec Strings est que Java a un concept de "interning" Strings, et cela est (effectivement) automatiquement effectué sur tous les littéraux de chaîne dans votre code. Cela signifie que si vous avez deux littéraux de chaîne équivalents dans votre code (même s'ils sont dans des classes différentes), ils se réfèrent tous deux au même
String
objet. Cela fait que l'==
opérateur revienttrue
plus souvent que ce à quoi on pourrait s'attendre.la source
En bref - vous pouvez avoir deux objets String qui contiennent les mêmes caractères mais sont des objets différents (dans des emplacements de mémoire différents). L'opérateur == vérifie que deux références pointent vers le même objet (emplacement mémoire), mais la méthode equals () vérifie si les caractères sont les mêmes.
Habituellement, vous souhaitez vérifier si deux chaînes contiennent les mêmes caractères, et non si elles pointent vers le même emplacement mémoire.
la source
la source
Oui, il est utilisé tout le temps pour les tests. Il est très probable que le cadre de test utilise .equals () pour des comparaisons comme celles-ci.
Ci-dessous un lien expliquant "l'erreur d'égalité de chaîne". Essentiellement, les chaînes en Java sont des objets et lorsque vous comparez l'égalité des objets, elles sont généralement comparées en fonction de l'adresse mémoire et non en fonction du contenu. Pour cette raison, deux chaînes n'occuperont pas la même adresse, même si leur contenu est identique, elles ne correspondront donc pas correctement, même si elles se ressemblent lors de l'impression.
http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/
la source
La JUnit
assertEquals(obj1, obj2)
appelle en effetobj1.equals(obj2)
.Il y a aussi
assertSame(obj1, obj2)
ce qui le faitobj1 == obj2
(c'est-à-dire qu'il vérifie celaobj1
etobj2
fait référence à la même instance), ce que vous essayez d'éviter.Alors tu vas bien.
la source
http://leepoint.net/notes-java/data/strings/12stringcomparison.html
String
est unObject
en java, donc il tombe dans cette catégorie de règles de comparaison.la source