66 votes

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

Je suis confus au sujet de StringPool en Java. Je suis tombé dessus en lisant le chapitre sur les chaînes en Java. Veuillez m'aider à comprendre, en termes simples, ce que StringPool fait réellement.

124voto

Nikita Rybak Points 36641

Cette impression true (même si nous n'utilisons pas equals méthode : manière correcte de comparer des chaînes de caractères)

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

Lorsque le compilateur optimise vos chaînes de caractères, il voit que les deux s y t ont la même valeur et vous n'avez donc besoin que d'un seul objet chaîne. C'est sûr car String est immuable en Java.
En conséquence, les deux s y t pointent vers le même objet et un peu de mémoire économisée.

Le nom "string pool" vient de l'idée que toutes les chaînes de caractères déjà définies sont stockées dans un "pool" et qu'avant de créer de nouvelles chaînes de caractères, il faut en créer de nouvelles. String le compilateur d'objets vérifie si une telle chaîne est déjà définie.

36voto

MStodd Points 2806

Je ne pense pas qu'il fasse grand chose, on dirait que c'est juste un cache pour les chaînes littérales. Si vous avez plusieurs chaînes dont les valeurs sont les mêmes, elles pointeront toutes vers le même littéral de chaîne dans le pool de chaînes.

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

Dans le cas 1, le littéral s1 est nouvellement créé et conservé dans le pool. Mais dans le cas 2, le s2 littéral fait référence au s1, il n'en créera pas un nouveau à la place.

if(s1 == s2) System.out.println("equal"); //Prints equal. 

String n1 = new String("Arul"); 
String n2 = new String("Arul"); 
if(n1 == n2) System.out.println("equal"); //No output.  

http://p2p.wrox.com/java-espanol/29312-string-pooling.html

17voto

Andreas_D Points 64111

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

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

Cela peut ne pas se produire - C'est un indice, qu'il y a quelque chose de spécial à propos String objets. En général, l'invocation d'un constructeur toujours créer une nouvelle instance de la classe. Ce n'est pas le cas avec les chaînes de caractères, en particulier lorsque les objets Chaîne sont "créés" avec des littéraux. Ces chaînes sont stockées dans un magasin global (pool) - ou du 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 machine virtuelle renvoie une référence à l'objet du pool. En pseudo-code, cela peut se passer comme suit :

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 y b contiennent des références à le même objet. Dans ce cas, nous avons (a == b) && (a.equals(b)) == true .

Ce n'est pas le cas si on utilise le constructeur :

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

Encore une fois, "one" est créée sur le pool mais ensuite 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 une piscine à cordes ? Les chaînes et surtout les littéraux de chaînes sont largement utilisés dans le code Java typique. Et elles sont immuables. Et le fait d'être immuable permet de mettre les chaînes en cache pour économiser de la mémoire et augmenter les performances (moins d'effort pour la création, moins de déchets à collecter).

En tant que programmeurs, nous n'avons pas besoin de nous préoccuper du pool de chaînes de caractères, tant que nous gardons à l'esprit :

  • (a == b) && (a.equals(b)) peut être true o false ( toujours utiliser equals pour comparer des chaînes de caractères)
  • N'utilisez pas la réflexion pour changer le support. char[] d'une chaîne (car vous ne savez pas qui est en train d'utiliser cette chaîne)

17voto

cHao Points 42294

Lorsque la JVM charge des classes, ou voit une chaîne de caractères littérale, ou du code intern s une chaîne de caractères, il ajoute la chaîne à un pool majoritairement caché qui contient une copie de chaque chaîne de ce type. Si une autre copie est ajoutée, le runtime l'organise de manière à ce que tous les littéraux fassent référence au même objet chaîne. Ceci est appelé "interning". Si vous dites quelque chose comme

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

il reviendra true car le premier et le second "test" sont en fait le même objet. Comparer des chaînes de caractères internées de cette façon peut être très difficile, beaucoup plus vite que String.equals car il n'y a qu'une seule comparaison de référence au lieu d'une série de comparaisons. char comparaisons.

Vous pouvez ajouter une chaîne au pool en appelant String.intern() qui vous renverra la version poolée de la chaîne (qui pourrait être la même chaîne que celle que vous êtes en train d'interner, mais vous seriez fou de vous fier à cela -- vous ne pouvez souvent pas être sûr du code qui a été chargé et exécuté jusqu'à présent et qui a interné la même chaîne). La version mutualisée (la chaîne retournée par intern ) sera égal à tout littéral identique. Par exemple :

String s1 = "test";
String s2 = new String("test");  // "new String" guarantees a different object

System.out.println(s1 == s2);  // should print "false"

s2 = s2.intern();
System.out.println(s1 == s2);  // should print "true"

2voto

anna Points 205

http://www.xyzws.com/Javafaq/what-is-string-literal-pool/3 . Une autre réponse que vous pouvez vérifier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X