Was ist Stringpool in Java? [duplicate]

Lesezeit: 7 Minuten

Was ist Stringpool in Java duplicate
Subhransu Mishra

Ich bin verwirrt über StringPool in Java. Ich bin darauf gestoßen, als ich das String-Kapitel in Java gelesen habe. Bitte helfen Sie mir, in Laiensprache zu verstehen, was StringPool tatsächlich tut.

Was ist Stringpool in Java duplicate
Nikita Rybak

Das druckt true (auch wenn wir es nicht verwenden equals Methode: Korrekte Methode zum Vergleichen von Zeichenfolgen)

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

Wenn der Compiler Ihre Zeichenfolgenliterale optimiert, erkennt er beides s und t haben den gleichen Wert und benötigen daher nur ein String-Objekt. Es ist sicher, weil String ist in Java unveränderlich.
Als Ergebnis beides s und t zeigen auf das gleiche Objekt und etwas Speicher gespart.

Der Name ‘String-Pool’ kommt von der Idee, dass alle bereits definierten Strings in einem ‘Pool’ gespeichert werden und vor dem Erstellen neuer String Der Objektcompiler prüft, ob eine solche Zeichenfolge bereits definiert ist.

  • Java hat Wrapper-Typen für primitive Typen und diese Klassen sind auch unveränderlich. Wie Integer, Charecter und Double …. etc. Haben sie auch einen Pool, um Speicher zu sparen? Wenn nicht, was ist das Besondere an String, um einen Pool zu haben?

    – Punith Raj

    2. Februar 2015 um 9:21 Uhr


  • @PunithRaj Ich bin mir nicht sicher! Ich bezweifle es jedoch. int ist zum Beispiel nur 4 Byte groß, sodass Sie am Ende nicht so viel sparen, wenn zwei Integer auf dieselbe Stelle im Speicher zeigen. Im Gegenteil, wenn Sie einen „Integer-Pool“ pflegen müssen, um sich wiederholende Werte zu erkennen, wird wahrscheinlich mehr Speicher verschwendet, als Sie sparen, wenn Sie doppelte Werte vermeiden.

    – Nikita Rybak

    3. Februar 2015 um 10:49 Uhr

  • @PunithRaj String ist kein primitiver Datentyp (technisch/implementierungstechnisch) und String hat keine Wrapper-Klasse wie char/int.

    – Benutzer3240361

    17. Februar 2015 um 10:49 Uhr


  • @PunithRaj String ist nicht primitiv wie die anderen Typen, die Sie angeben, wird aber oft als solche behandelt – daher ist es in der Java-Sprache eher “besonders”. Java führt jedoch eine ähnliche Optimierung mit Wrapper-Klassen durch: Wenn der umrahmte Wert p wahr, falsch, ein Byte oder ein Zeichen im Bereich \u0000 bis \u007f oder eine Ganzzahl oder eine kurze Zahl zwischen -128 und 127 (einschließlich) ist, dann seien r1 und r2 die Ergebnisse von zwei beliebige Boxumwandlungen von p. Es gilt immer r1 == r2. Diese gemeinsamen Werte werden ähnlich “gepoolt”. StringS.

    – ethanbustad

    17. März 2015 um 17:37 Uhr


  • Guter Kommentar @PunithRaj, Sie sollten es zu einer separaten Frage machen.

    – Orchideenrudra

    31. Mai 2015 um 14:11 Uhr

1646245630 639 Was ist Stringpool in Java duplicate
MStodd

Ich glaube nicht, dass es wirklich viel macht, es sieht so aus, als wäre es nur ein Cache für String-Literale. Wenn Sie mehrere Strings haben, deren Werte gleich sind, zeigen sie alle auf dasselbe String-Literal im String-Pool.

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

Im Fall 1 wird das Literal s1 neu erstellt und im Pool gehalten. Aber in Fall 2 bezieht sich das Literal s2 auf s1, es wird stattdessen kein neues erstellt.

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

1646245630 704 Was ist Stringpool in Java duplicate
Andreas Dölk

Beginnen wir mit einem Zitat aus der Spezifikation der virtuellen Maschine:

Das Laden einer Klasse oder Schnittstelle, die ein String-Literal enthält, kann ein neues String-Objekt (§2.4.8) erstellen, um dieses Literal darzustellen. Dies tritt möglicherweise nicht auf, wenn ein String-Objekt bereits erstellt wurde, um ein früheres Vorkommen dieses Literals darzustellen, oder wenn die String.intern-Methode für ein String-Objekt aufgerufen wurde, das dieselbe Zeichenfolge wie das Literal darstellt.

Dies darf nicht vorkommen – Das ist ein Hinweis, dass es etwas Besonderes gibt String Objekte. Normalerweise wird das Aufrufen eines Konstruktors immer Erstellen Sie eine neue Instanz der Klasse. Dies ist bei Strings nicht der Fall, insbesondere wenn String-Objekte mit Literalen ‘erzeugt’ werden. Diese Strings werden in einem globalen Speicher (Pool) gespeichert – oder zumindest die Referenzen werden in einem Pool gehalten, und immer wenn eine neue Instanz eines bereits bekannten Strings benötigt wird, gibt der VM einen Verweis auf das Objekt aus dem Pool zurück. Im Pseudocode kann das so aussehen:

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")] 

Also in diesem Fall Variablen a und b Verweise auf halten das Gleiche Objekt. In diesem Fall haben wir (a == b) && (a.equals(b)) == true.

Dies ist nicht der Fall, wenn wir den Konstruktor verwenden:

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

Aufs Neue, "one" wird im Pool erstellt, aber dann erstellen wir eine neue Instanz aus demselben Literal, und in diesem Fall führt dies zu (a == b) && (a.equals(b)) == false

Damit warum Haben wir einen String-Pool? Strings und insbesondere String-Literale werden in typischem Java-Code häufig verwendet. Und sie sind unveränderlich. Und da es unveränderlich ist, kann String zwischengespeichert werden, um Speicher zu sparen und die Leistung zu steigern (weniger Aufwand für die Erstellung, weniger zu sammelnder Müll).

Als Programmierer müssen wir uns nicht viel um den String-Pool kümmern, solange wir im Hinterkopf behalten:

  • (a == b) && (a.equals(b)) vielleicht true oder false (immer verwenden equals Strings vergleichen)
  • Verwenden Sie keine Reflektion, um den Hintergrund zu ändern char[] eines Strings (da Sie nicht wissen, wer diesen String tatsächlich verwendet)

  • Wenn du tun Wenn Sie sich um den String-Pool kümmern, gibt es das Potenzial für massive Leistungssteigerungen in Anwendungen, die eine kleine Gruppe von Strings ausgiebig verwenden, normalerweise als Token oder Schlüsselwörter. Sobald die Zeichenfolgen interniert sind, wird der Vergleich zu einem einzelnen == Anstelle des Funktionsaufrufs zwei length()-Aufrufe und eine potenzielle Menge von Zeichenvergleichen, die damit einhergehen würden equals.

    – chao

    27. September 2010 um 9:09 Uhr


  • @cHao Aus Sicherheitsgründen und Konsistenz können Sie immer noch verwenden String.equals() mit internierten Saiten, weil String.equals() zuerst tut ein == Vergleich

    – bcoughlan

    1. Oktober 2014 um 11:00 Uhr

  • @bcoughlan: == ist so sicher und konsistent wie equals – Es wird nur missverstanden. Menschen, die es im Allgemeinen mit Objekten verwenden, fallen in zwei Kategorien. Es gibt diejenigen, die die Semantik von Wert und Identität nicht verstehen (und dass == mit Referenztypen Identität vergleicht) – diese Leute sollte Verwenden Sie immer String.equals. Dann gibt es diejenigen, die verstehen, aber bewusst sind wählen Identität. Und das funktioniert genauso zuverlässig, solange Sie wissen, woher Ihre Objekte stammen. Es gibt einen Grund == mit Objekten arbeitet – und vor allem, warum es nicht einfach anruft equals.

    – chao

    1. Oktober 2014 um 14:02 Uhr

  • @cHao Der Schlüssel ist “solange Sie wissen, woher Ihre Objekte stammen”. if (s1==s2) sieht für die meisten Leute verdächtig nach einem Fehler aus (und wird von FindBugs gekennzeichnet). Ich habe nur darauf hingewiesen, dass Sie immer noch die Leistungssteigerungen von Vergleichen mit String-Pooling erhalten können, ohne Code zu schreiben, der davon ausgeht, dass Strings interniert sind

    – bcoughlan

    1. Oktober 2014 um 14:59 Uhr


  • @bcoughlan: Du kannst bekommen etwas der Boosts, aber Sie haben immer noch einen Methodenaufruf. Im meine Prüfungen, trägt dieser Methodenaufruf erheblich – wie +100 % – zur Gesamtlaufzeit der Funktion bei. Und das in einem Test, der zumindest ein klein wenig realistisch sein soll.

    – chao

    1. Oktober 2014 um 17:23 Uhr

  • Ich glaube eigentlich nicht, dass es zur Laufzeit gemacht wird. Selbst einfachste Zeichenfolgen, die mit Methoden erstellt wurden, werden nicht gepoolt. Beispielsweise funktioniert das Beispiel aus meiner Antwort nicht, wenn ich es verwende konkat anstatt +

    – Nikita Rybak

    27. September 2010 um 6:41 Uhr

  • @Nikita: Das liegt daran concat kann nicht so einfach wegoptimiert werden. Die Saiten katten zusammen mit + würde wahrscheinlich von jedem Compiler mit Selbstachtung vorkattiert werden, da sich der Wert nie ändert. Aber der Compiler kann nicht wirklich erraten, ob eine Funktion immer denselben Wert zurückgibt (einige tun dies nicht), also würde er es nicht versuchen. Wenn du benutzt concat Stattdessen würden in Ihrem Beispiel “ab”, “c”, “a” und “bc” interniert, “abc” jedoch nicht (weil es kein Literal ist und Ihr Code dies nicht tut intern es). Allerdings mit + Ein anständiger Compiler wird sehen, dass beide Zeichenfolgen “abc” sind, und das kompilieren.

    – chao

    27. September 2010 um 8:25 Uhr


  • Das Praktikum würde verfügen über zur Laufzeit durchgeführt werden, da (1) der Pool immer leer beginnt und (2) zwei verschiedene Klassen jeweils “abc” enthalten könnten. Wenn das Internieren eine Sache zur Kompilierzeit wäre und beide Klassen geladen würden, würden am Ende zwei “abc”s im String-Pool sein, was den ganzen Zweck des String-Pools zunichte macht.

    – chao

    27. September 2010 um 8:45 Uhr


914880cookie-checkWas ist Stringpool in Java? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy