Question

Je sais que == présente des problèmes lors de la comparaison de deux chaînes . Il semble que String.equals () soit une meilleure approche. Eh bien, je fais des tests sur 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'obtiendrez pas l'avantage de voir quelles sont les valeurs attendues et réelles en cas d'échec.

Sur une note connexe, quelqu'un at-il un lien vers une page ou un fil de discussion expliquant clairement les problèmes liés à str1 == str2 ?

Était-ce utile?

La solution

Vous devez toujours utiliser .equals () lorsque vous comparez Chaînes en Java.

JUnit appelle la méthode .equals () pour déterminer l'égalité dans la méthode assertEquals (Object o1, Object o2) .

Donc, vous êtes vraiment sûr d'utiliser assertEquals (string1, string2) . (Parce que les String sont des objets s)

Voici un lien vers une grande question Stackoverflow concernant certaines des différences entre == et .equals () .

Autres conseils

assertEquals utilise la méthode égal à à des fins de comparaison. Il existe une assertion différente, assertSame , qui utilise l'opérateur == .

Pour comprendre pourquoi == ne devrait pas être utilisé avec des chaînes, vous devez comprendre ce que fait == : il effectue un contrôle d'identité. En d'autres termes, a == b vérifie si a et b font 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. La méthode equals peut quant à elle être remplacée par des classes. Bien que son comportement par défaut (dans la classe Object ) consiste à effectuer une vérification d’identité à l’aide de l’opérateur == , de nombreuses classes, notamment String , écrasent à la place, faire une "équivalence" vérifier. Dans le cas de String , au lieu de vérifier si a et b se rapportent au même objet, a.equals (b) vérifie si les objets auxquels ils font référence sont des chaînes contenant exactement les mêmes caractères.

Temps d’analogie: imaginez que chaque objet String soit une feuille de papier sur laquelle quelque chose est écrit. Disons que j'ai deux feuilles de papier avec " Foo " écrit dessus, et un autre avec " Bar " écrit dessus. Si je prends les deux premiers bouts de papier et que j'utilise == pour les comparer, cela retournera false car il s'agit essentiellement de demander "S'agit-il du même morceau de papier?" . Il n'est même pas nécessaire de regarder ce qui est écrit sur le papier. Le fait que je lui donne deux bouts de papier (plutôt que le même deux fois) signifie qu'il retournera false . Si j'utilise est égal à , cependant, la méthode égal à lira les deux bouts de papier et verra qu'ils disent la même chose ("Foo"), et ainsi de suite. ll renverra true .

Le problème avec Strings est que Java a le concept "interning". Chaînes, et cela est (effectivement) automatiquement effectué sur les littéraux de chaîne de votre code. Cela signifie que si vous avez deux littéraux de chaîne équivalents dans votre code (même s'ils appartiennent à des classes différentes), ils feront tous deux référence au même objet String . Cela fait que l'opérateur == renvoie true plus souvent que l'on pourrait s'y attendre.

En résumé, vous pouvez avoir deux objets String contenant les mêmes caractères mais qui sont différents (dans des emplacements de mémoire différents). L'opérateur == vérifie que deux références pointent sur le même objet (emplacement mémoire), mais la méthode equals () vérifie si les caractères sont identiques.

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.

Oui, il est utilisé tout le temps pour les tests. Il est très probable que la structure de test utilise .equals () pour de telles comparaisons.

Vous trouverez ci-dessous un lien expliquant "l'erreur d'égalité de chaîne". En gros, les chaînes en Java sont des objets, et lorsque vous comparez l'égalité d'objet, elles sont généralement comparées en fonction de l'adresse de la mémoire et non du contenu. De ce fait, deux chaînes n'occuperont pas la même adresse, même si leur contenu est identique, elles ne correspondent donc pas correctement, même si elles se ressemblent à l'impression.

http: //blog.enrii. com / 2006/03/15 / java-string-égalité-commune-erreur /

public class StringEqualityTest extends TestCase {
    public void testEquality() throws Exception {
        String a = "abcde";
        String b = new String(a);
        assertTrue(a.equals(b));
        assertFalse(a == b);
        assertEquals(a, b);
    }
}

Le JUnit assertEquals (obj1, obj2) appelle effectivement obj1.equals (obj2) .

Il y a aussi assertSame (obj1, obj2) qui fait obj1 == obj2 (c'est-à-dire qu'il vérifie que obj1 et obj2 font référence à la même instance, ce que vous essayez d'éviter.

Alors ça va.

  

" L'opérateur == vérifie si deux objets sont exactement les mêmes Objet . "

http://leepoint.net/notes-java/data/strings /12stringcomparison.html

String est un Object en java. Il entre donc dans cette catégorie de règles de comparaison.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top