Qu'est-ce que String pool en Java? [dupliquer]

cette question a déjà une réponse ici:

  • Qu'est-ce que Java string pool et en quoi "s" diffère-t-il de new String("s")? [duplicate] 6 réponses

Je suis confus au sujet de StringPool en Java. Je suis tombé sur ceci en lisant le chapitre String en Java. Merci de m'aider comprenez, en termes simples, ce que StringPool fait réellement.

63
demandé sur the Tin Man 2010-09-27 09:34:39

4 réponses

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

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

quand le compilateur optimise vos littérales de corde, il voit que les deux s et t ont la même valeur et donc vous n'avez besoin que d'un seul objet de corde. C'est sans danger parce que String est immuable en Java.

En conséquence, les deux s et t pointent vers le même objet et une petite mémoire enregistrer.

nom ' string pool 'vient 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 nouveau String objet compilateur vérifie si une telle chaîne est déjà définie.

116
répondu Nikita Rybak 2010-09-27 05:45:05

Je ne pense pas que ça fasse grand chose, on dirait que c'est juste une cache pour des chaînes de caractères. Si vous avez plusieurs chaînes dont les valeurs sont les mêmes, elles pointeront toutes vers la même chaîne littérale dans le pool de chaînes.

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

dans le cas 1, literal S1 est créé à nouveau et conservé dans la piscine. Mais dans le cas 2, littéral S2 renvoyer le s1, il ne créera pas de nouvelle à 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

36
répondu MStodd 2011-02-21 07:00:19

commençons par une citation de la machine virtuelle spec:

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

cela ne peut pas se produire - c'est un indice, qu'il ya quelque chose de spécial sur String objets. Habituellement, invoquer un constructeur va toujours créer une nouvelle instance de la classe. Ce n'est pas le cas avec les cordes, surtout lorsque les objets String sont "créés" avec des caractères littéraux. Ces chaînes sont stockées dans un Global store (pool) - ou au moins les références sont conservées dans un pool, et chaque fois qu'une nouvelle instance d'un déjà les chaînes connues sont nécessaires, la vm renvoie une référence à l'objet de la liste. En pseudo code, cela peut se passer 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")] 

ainsi, dans ce cas, les variables a et 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 nous utilisons le constructeur:

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

encore, "one" est créé sur la piscine mais alors nous créer une nouvelle instance à partir du même littéral, et dans ce cas, il mène à (a == b) && (a.equals(b)) == false

donc pourquoi avons-nous un bassin de cordes? Les chaînes et en particulier les caractères littéraux sont largement utilisés dans le code Java typique. Et ils sont immuables. Et Être immuable a permis à la chaîne de cache d'économiser de la mémoire et d'augmenter les performances (Moins d'effort pour la création, moins de déchets à collecter).

en tant que programmeurs, nous n'avons pas à nous soucier la Chaîne de la piscine, aussi longtemps que nous gardons à l'esprit:

  • (a == b) && (a.equals(b)) peut-être true ou 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 utilise cette chaîne)
17
répondu Andreas_D 2010-09-27 06:18:22

quand la JVM charge des classes, ou voit autrement une chaîne littérale, ou quelque code intern s une chaîne, elle ajoute la chaîne à une table de recherche principalement cachée qui a une copie de chacune de ces chaînes. Si une autre copie est ajoutée, le runtime l'organise de sorte que toutes les lettres se réfèrent au même objet string. Ceci est appelé "stage". Si vous dites quelque chose comme

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

il retournera true , parce que le premier et le second "test" sont en fait les mêmes objet. Comparer les cordes internes de cette façon peut être beaucoup, beaucoup plus rapide que String.equals , car il ya une seule comparaison de référence plutôt qu'un tas de char comparaisons.

vous pouvez ajouter une chaîne de caractères à la liste en appelant String.intern() , ce qui vous donnera la version de la chaîne de caractères (qui pourrait être la même chaîne que vous internez, mais vous seriez fou de vous y fier -- vous ne pouvez souvent pas être sûr exactement quel code a été chargé et d'exécuter jusqu'à présent et internés de la même chaîne). La version groupée (la chaîne renvoyée de intern ) sera égale à n'importe quel 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"
14
répondu cHao 2016-01-13 17:36:37