[JAVA] String- und Heap-Bereich und konstanter Pool

Java-Speicherbereich

Grob!

Registrierung
Existiert in CPU und kann nicht gesteuert werden
Stapelbereich
Basistyp, Referenzwert wird gespeichert
Die Speicherverwaltung erfolgt durch Hin- und Herbewegen des Punkts
Heap-Bereich
Objekt erstellt von new
statischer Bereich
Wie das Wort schon sagt, statische Mitglieder
constant pool
Daten, die zur Kompilierungszeit bestätigt wurden und in .class + other vorhanden sind
Nicht-RAM-Bereich
hdd usw.

String- und Heap-Bereich und konstanter Pool

Hauptthema: Ich möchte "Daten überprüfen, die zum Zeitpunkt der Kompilierung bestätigt wurden und in .class vorhanden sind".

Überprüfung vertrauter Inhalte

Im konstanten Pool generiert

String a1 = "aaa";
String a2 = "aaa";
System.out.println(a1 == a2); // true
  1. "aaa" wird im Contant-Pool-Bereich generiert, und der Referenzwert a1, der auf "aaa" zeigt, wird im Stack-Bereich generiert.
  2. Da sich im Bereich des Contant-Pools "aaa" befindet, wird im Stapelbereich ein Referenzwert a2 generiert, der auf "aaa" zeigt.
  3. Da sowohl a1 als auch a2 die Adresse "aaa" enthalten, wird dies wahr.

Im Heap-Bereich generiert

String a3 = new String("aaa");
String a4 = new String("aaa");
System.out.println(a3 == a4); // false
  1. "aaa" wird im Heap-Bereich erzeugt, und der Referenzwert a3, der auf "aaa" zeigt, wird im Stapelbereich erzeugt.
  2. "aaa" wird im Heap-Bereich erzeugt, und der Referenzwert a4, der auf "aaa" zeigt, wird im Stapelbereich erzeugt.
  3. a3 und a4 sind falsch, weil sie unterschiedliche "aaa" -Adressen enthalten.

Generiert in konstantem Pool, Heap-Bereich

String a5 = "aaa";
String a6 = new String("aaa");
System.out.println(a5 == a6); // false
  1. "aaa" wird im konstanten Poolbereich erzeugt, und der Referenzwert a5, der auf "aaa" zeigt, wird im Stapelbereich erzeugt.
  2. "aaa" wird im Heap-Bereich generiert, und der Referenzwert a6, der auf "aaa" zeigt, wird im Stapelbereich generiert.
  3. a5 und a6 sind falsch, weil sie unterschiedliche "aaa" -Adressen enthalten.

Überprüfung von etwas ungewöhnlichen Inhalten

Konstante + Konstante

String a1 = "ab";
String a2 = "a" + "b";
System.out.println(a1 == a2); // true
  1. "ab" wird im konstanten Poolbereich erzeugt, und der Referenzwert a1, der auf "ab" zeigt, wird im Stapelbereich erzeugt.
  2. "a" ist eine Konstante, "b" ist eine Konstante, also ist a2 = "ab" zur Kompilierungszeit. Es wird ein Referenzwert a2 generiert, der auf "ab" zeigt, das in der konstanten Abfrage vorhanden ist.
  3. Da sowohl a1 als auch a2 die Adresse "ab" enthalten, wird dies wahr.
  4. Als ich es mit Dekompilierung betrachtete, war es String a2 =" ab ";.

Konstante + neue Zeichenfolge ("")

String a1 = "ab";
String a2 = "a" + new String("b");
System.out.println(a1 == a2); // false
  1. "ab" wird im konstanten Poolbereich erzeugt, und der Referenzwert a1, der auf "ab" zeigt, wird im Stapelbereich erzeugt.
  2. Der neue String ("") wird beim Kompilieren nicht finalisiert. Daher wird zum Zeitpunkt der Ausführung "b" im Heap-Bereich erzeugt, und ferner wird der Heap-Bereich "ab" erzeugt.
  3. Infolgedessen sind a1 und a2 falsch, da sie unterschiedliche "ab" -Adressen enthalten.

Konstante + Referenzwert

String a1 = "ab";
String a2 = "b";
String a3 = "a" + a2;
System.out.println(a1 == a3); // false
  1. "ab" wird im konstanten Poolbereich erzeugt, und der Referenzwert a1, der auf "ab" zeigt, wird im Stapelbereich erzeugt.
  2. "b" wird im konstanten Poolbereich erzeugt, und der Referenzwert a2, der auf "ab" zeigt, wird im Stapelbereich erzeugt.
  3. Da a2 ein Referenzwert ist, wird er zur Kompilierungszeit nicht festgelegt. Daher wird zum Zeitpunkt der Ausführung im Heap-Bereich "ab" generiert, und a3 zeigt darauf.
  4. Infolgedessen ist a1 ein konstanter Pool und a3 ein Heap-Bereich, sodass er falsch wird.

Konstante + Finale

String a1 = "ab";
final String a2 = "b";
String a3 = "a" + a2;
System.out.println(a1 == a3); // true
  1. Mit final wird a2 als Konstante betrachtet und a3 ist konstant + konstant = konstant.

Betrachtet man es mit dem Dekompiler, so wurde es wie folgt kompiliert.

String a1 = "ab";
String a2 = "b";
String a3 = "ab";
System.out.println(a1 == a3);

String.intern() Eine Methode, die den konstanten Pool erweitern kann.

String-Instanz .intern ()

  1. Wenn der gleiche Wert im Konstantenpool vorhanden ist, geben Sie den Referenzwert zurück.
  2. Wenn im Konstantenpool nicht derselbe Wert vorhanden ist, generieren Sie einen Wert im Konstantenpool und geben Sie den Referenzwert zurück.
String a1 = "ab";
String a2 = new String("ab");
System.out.println(a1 == a2); // false
a2 = a2.intern();
System.out.println(a1 == a2); // true
  1. "ab" wird im konstanten Poolbereich erzeugt, und der Referenzwert a1, der auf "ab" zeigt, wird im Stapelbereich erzeugt.
  2. "ab" wird im Heap-Bereich erzeugt, und der Referenzwert a2, der auf "ab" zeigt, wird im Stapelbereich erzeugt.
  3. Falsch wird weggelassen.
  4. Da a2.intern () und "ab" im Konstantenpool vorhanden sind, geben Sie die "ab" -Adresse des Konstantenpools an a2 zurück.
  5. Sowohl a1 als auch a2 zeigen im kontinuierlichen Pool auf "ab", also ist es wahr.

Bonus: Warum String + nicht gut abschneidet

String s = null;
for(int i = 0; i < 100; ++i) {
    s = s + "a";
}

Basierend auf der bisherigen Überprüfung Da s in s +" a "; eine Variable ist, wird bei jeder Ausführung ein neues Objekt erstellt und zerstört.

Recommended Posts

String- und Heap-Bereich und konstanter Pool
String und Stringbuffer und String Builder
String-Literale und Instanzen
[Java] Vergleich von Zeichenketten und && und ||
[Java] Stapelbereich und statischer Bereich
[Java] Über String und StringBuilder
String-Verkettung und Zeilenumbrüche