Si == compare les références en Java, pourquoi est-il évalué à true avec ces chaînes?

Comme indiqué, l’opérateur == compare les références d’object pour vérifier si elles font référence au même object sur un segment de mémoire. Si oui, pourquoi est-ce que je reçois le “Equal” pour ce morceau de code?

public class Salmon { public static void main(Ssortingng[] args) { Ssortingng str1 = "Str1"; Ssortingng str2 = "Str1"; if (str1 == str2) { System.out.println("Equal"); } else { System.out.println("Not equal"); } } } 

Le programme imprimera Equal . (Au moins en utilisant Sun Hotspot et Suns Javac.) Ici, la démonstration est donnée sur http://ideone.com/8Urrrk.

Cela est dû au fait que les constantes littérales de chaîne sont stockées dans un pool de chaînes et que les références de chaîne peuvent être réutilisées.

Lectures complémentaires:

  • Qu’est-ce qu’un pool de chaînes de caractères?
  • Chaîne interning

Ceci cependant:

 public class Salmon { public static void main(Ssortingng[] args) { Ssortingng str1 = "Str1"; Ssortingng str2 = new Ssortingng("Str1"); if (str1 == str2) { System.out.println("Equal"); } else { System.out.println("Not equal"); } } } 

Sera imprimé Not equal puisqu’il est new d’introduire une nouvelle référence.

Donc, règle de base: comparez toujours les chaînes en utilisant la méthode equals .

Java stocke toutes les chaînes dans une table de chaînes en interne au cours d’une exécution. Les références aux deux chaînes sont identiques car elles sont stockées au même endroit en mémoire. Par conséquent, Equal .

Votre déclaration est juste, que == compare les références d’object. Essayez la même chose avec n’importe quelle classe sauf Ssortingngs et vous n’obtiendrez pas le même résultat.

Ce code ne sera pas imprimé Equal .
Mais si les deux chaînes étaient identiques, ce cas serait spécial.

Maintenant que vous avez mis à jour votre code, c’est le cas:

Une explication simple (mais pas totalement exacte) est que le compilateur voit que les deux chaînes sont identiques et fait quelque chose comme:

 Ssortingng str1 = "Str1"; Ssortingng str2 = str1; 

Ce qui se passe réellement ici, c’est que le compilateur voit la chaîne littérale et la place dans le “pool de chaînes littérales”.

Comme une chaîne ne peut pas être modifiée (elle est immuable), les valeurs littérales des chaînes (celles trouvées lors de la compilation) sont placées dans un “pool”.
De cette façon, si deux chaînes littérales différentes ayant le même contenu (comme dans ce cas particulier), la mémoire n’est pas perdue pour stocker deux fois “Str1” et “Str1”.

Gens, vous oubliez que le processus de placement de chaînes littérales dans le pool s’appelle “interning”. La classe Ssortingng a une méthode appelée intern (). Cette méthode place n’importe quelle chaîne dans le pool, même si ce n’est pas le cas initialement (pas littéralement). Cela signifie que le code ressemble à ceci:

 Ssortingng a = "hello"; Ssortingng b = new Ssortingng("hello"); b = b.intern(); System.out.println(a == b); 

affichera ” true “. Maintenant, pourquoi quelqu’un aurait-il besoin de ça? Comme vous pouvez l’imaginer, la comparaison de chaînes a.equals(b) peut prendre du temps si les chaînes ont la même longueur mais sont différentes vers la fin. (Il suffit de regarder le code source .equals ().).

Cependant, comparer directement les références revient à comparer des nombres entiers (pointeurs en C), ce qui est proche de l’instant.

Alors, qu’est-ce que cela vous donne? La vitesse. Si vous devez comparer les mêmes chaînes plusieurs fois, les performances de votre programme en bénéficieront énormément si vous les placez en interne . Toutefois, si vous comparez les chaînes une seule fois, il n’y aura aucun gain de performances car le processus d’interning lui-même utilise equals ().

J’espère que cela explique cela.

Merci

Les commentaires ci-dessus l’ont bien résumé.

Je n’ai pas d’environnement Java à scope de main, mais voici ce que je devrais faire pour clarifier les choses (j’espère que cela fonctionne comme prévu).

 Ssortingng str1 = "Str1"; Ssortingng str2 = "Str"; str2 += "1"; 

Devrait maintenant imprimer Pas égal