Qu’est-ce qu’un pool de chaînes en Java?

Je suis confus à propos de SsortingngPool en Java. Je suis tombé sur cela en lisant le chapitre Ssortingng de Java. S’il vous plaît aidez-moi à comprendre, en termes simples, ce que SsortingngPool fait réellement.

Cela imprime true (même si nous n’utilisons pas la méthode equals : façon correcte de comparer les chaînes)

  Ssortingng s = "a" + "bc"; Ssortingng t = "ab" + "c"; System.out.println(s == t); 

Lorsque le compilateur optimise vos littéraux de chaîne, il voit que s et t ont la même valeur et vous n’avez donc besoin que d’un object chaîne. C’est sûr parce que Ssortingng est immuable en Java.
Par conséquent, s et t désignent le même object et une petite quantité de mémoire.

Le nom ‘pool de chaînes’ provient de l’idée que toutes les chaînes déjà définies sont stockées dans un ‘pool’ et avant de créer un nouvel object Ssortingng , le compilateur vérifie si une telle chaîne est déjà définie.

Je ne pense pas que cela fasse beaucoup, on dirait que c’est juste un cache pour les littéraux de chaîne. Si vous avez plusieurs chaînes dont les valeurs sont identiques, elles indiqueront toutes le même littéral de chaîne dans le pool de chaînes.

 Ssortingng s1 = "Arul"; //case 1 Ssortingng s2 = "Arul"; //case 2 

Dans le cas 1, le littéral s1 est créé nouvellement et conservé dans le pool. Mais dans le cas 2, littéral s2 renvoie le s1, il ne créera pas un nouveau à la place.

 if(s1 == s2) System.out.println("equal"); //Prints equal. Ssortingng n1 = new Ssortingng("Arul"); Ssortingng n2 = new Ssortingng("Arul"); if(n1 == n2) System.out.println("equal"); //No output. 

http://p2p.wrox.com/java-espanol/29312-ssortingng-pool.html

Commençons par une citation de la spécification de la machine virtuelle:

Le chargement d’une classe ou d’une interface contenant un littéral Ssortingng peut créer un nouvel object Ssortingng (§2.4.8) pour représenter ce littéral. Cela peut ne pas se produire si un object Ssortingng a déjà été créé pour représenter une occurrence précédente de ce littéral ou si la méthode Ssortingng.intern a été appelée sur un object Ssortingng représentant la même chaîne que le littéral.

Cela peut ne pas se produire – Ceci est un indice, il y a quelque chose de spécial à propos des objects Ssortingng . En général, l’appel d’un constructeur crée toujours une nouvelle instance de la classe. Ce n’est pas le cas avec les chaînes, en particulier lorsque les objects Ssortingng sont «créés» avec des littéraux. Ces chaînes sont stockées dans un magasin global (ou au moins les références sont conservées dans un pool) et chaque fois qu’une nouvelle instance d’une chaîne déjà connue est nécessaire, la vm renvoie une référence à l’object depuis le pool. En pseudo-code, ça peut aller comme ça:

 1: a := "one" --> if(pool[hash("one")] == null) // true pool[hash("one") --> "one"] return pool[hash("one")] 2: b := "one" --> if(pool[hash("one")] == null) // false, "one" already in pool pool[hash("one") --> "one"] return pool[hash("one")] 

Donc, dans ce cas, les variables a et b contiennent des références au même object. Dans ce cas, nous avons (a == b) && (a.equals(b)) == true .

Ce n’est pas le cas si nous utilisons le constructeur:

 1: a := "one" 2: b := new Ssortingng("one") 

Encore "one" fois, "one" est créé sur le pool mais nous créons une nouvelle instance à partir du même littéral, et dans ce cas, cela conduit à (a == b) && (a.equals(b)) == false

Alors, pourquoi avons-nous un pool de chaînes? Les chaînes et en particulier les littéraux de chaîne sont largement utilisés dans le code Java typique. Et ils sont immuables. Et être immuable autorisé à mettre en cache la chaîne pour économiser de la mémoire et augmenter les performances (moins d’efforts pour la création, moins de déchets à collecter).

En tant que programmeurs, nous n’avons pas à nous soucier du pool de Ssortingng, tant que nous gardons à l’esprit:

  • (a == b) && (a.equals(b)) peut être true ou false (utilisez toujours des equals pour comparer des chaînes)
  • N’utilisez pas la reflection pour changer le caractère de sauvegarde char[] d’une chaîne (car vous ne savez pas qui utilise cette chaîne)

Lorsque la machine virtuelle Java charge des classes, ou voit une chaîne littérale ou une chaîne de code intern , elle ajoute la chaîne à une table de recherche la plus souvent masquée, avec une copie de chaque chaîne. Si une autre copie est ajoutée, le moteur d’exécution l’arrange pour que tous les littéraux se réfèrent au même object de chaîne. Cela s’appelle “interning”. Si vous dites quelque chose comme

 Ssortingng s = "test"; return (s == "test"); 

il retournera true , car le premier et le deuxième “test” sont en fait le même object. Comparer les chaînes internes de cette façon peut être beaucoup, beaucoup plus rapide que Ssortingng.equals , car il y a une seule comparaison de référence plutôt qu’un tas de comparaisons de caractères.

Vous pouvez append une chaîne au pool en appelant Ssortingng.intern() , qui vous restituera la version groupée de la chaîne (qui pourrait être la même que celle que vous installez, mais vous seriez fou de compter dessus – – vous ne pouvez souvent pas savoir exactement quel code a été chargé et exécuté jusqu’à maintenant et interné la même chaîne). La version groupée (la chaîne renvoyée par intern ) sera égale à tout littéral identique. Par exemple:

 Ssortingng s1 = "test"; Ssortingng s2 = new Ssortingng("test"); // "new Ssortingng" guarantees a different object System.out.println(s1 == s2); // should print "false" s2 = s2.intern(); System.out.println(s1 == s2); // should print "true"