Skip to main content

Java Strings landen im String Constant Pool

Du kennst das.

Es ist abends.
Du sitzt gemütlich vor dem Fernseher.
Das Smartphone bimmelt.

Kein Anruf.
Nein – Eine Nachricht.

Du liest die Nachricht sofort und antwortest darauf.
Minuten später bekommst du die nächste Nachricht.

Und auch auf diese antwortest du.
Im Laufe des Abends entsteht daraus eine nette kleine Konversation.

Und eh du dich versiehst, sind im Chat-verlauf 50 neue Einträge.

Alles das – der komplette Verlauf ist Text.
Und um jetzt auf die Java Programmierung umzuschwenken.
Das alles wären Java Strings.

Strings sind Textwerte, welche eine besondere Stellung in sämtlichen Programmen haben.

Wieso eine besondere Stellung?
Ganz einfach- weil sie so oft vorkommen.

Unsere ganze menschliche Kommunikation ist daran ausgerichtet.
Im Chatprogramm wird dies sehr offensichtlich.

Wie sieht es in anderen Programmen aus?
Auch ein Programm, welches Rechnungen schreiben kann, braucht enorm viele Strings.
Denke an die Beschriftung auf den Button, an die Rechnungsparameter.

Und weil diese so oft vorkommen, nehmen sie auch viel Speicher in Anspruch.
Es wird klar, dass diese Strings oder Textwerte intern anders behandelt werden müssen, als alle anderen Objekte.

Objekte?

Ja – Java Strings sind echte Java Objekte.

Du kannst einen String auf zwei verschiedene Arten anlegen.

Ich bleibe im Chatprogramm und lege zwei Benutzer an.
Und den Namen lasse ich mir dann über die Konsole ausgeben.


public class ChatProgramm {
	
	public static void main(String[] args) {
		String benutzerEins = new String ("Matze"); //neues String-Objekt über Konstruktor erstellt
		String benutzerZwei = new String ("Melanie");//neues String-Objekt über Konstruktor erstellt
		
		System.out.println(benutzerEins);//Rückgabe: Matze
		System.out.println(benutzerZwei);//Rückgabe: Melanie

	}
}

Du siehst:
Ich habe zwei ganz normale Objekte der Klasse String erzeugt.
Im Konstruktor habe ich die Namen übergeben und somit existieren beide Objekte auf dem Heap.

Java Strings Pool verweise

Und weil diese sich auf dem Heap befinden, werden diese auch wie zwei ganz normale Objekte behandelt.

Zum Beispiel:
Wenn du einen der Strings zerstören bzw. löschen möchtest, brauchst du nur die Referenzvariable umswitchen.


public class ChatProgramm {
	
	public static void main(String[] args) {
		String benutzerEins = new String ("Matze"); //neues String-Objekt über Konstruktor erstellt
		String benutzerZwei = new String ("Melanie");//neues String-Objekt über Konstruktor erstellt
		
		System.out.println(benutzerEins);//Rückgabe: Matze
		System.out.println(benutzerZwei);//Rückgabe: Melanie

		benutzerEins=benutzerZwei; //umswitchen
		System.out.println(benutzerEins);//Benutzer eins heißt jetzt Melanie
	}
}

Java Strings Heap umswitchen

Und dann kommt der Garbage Collector und räumt diesen String vom Speicher.

Aber du kannst Strings auch anders anlegen.
Und zwar so.


public class ChatProgramm {
	
	public static void main(String[] args) {
		String benutzerEins = new String ("Matze"); //neues String-Objekt über Konstruktor erstellt
		String benutzerZwei = new String ("Melanie");//neues String-Objekt über Konstruktor erstellt
		String benutzerDrei = "Steffen"; //neues String Objekt ohne Konstruktor
		String benutzerVier = "Sabine"; //noch ein Objekt ohne Konstruktor
		
		System.out.println(benutzerEins);//Rückgabe: Matze
		System.out.println(benutzerZwei);//Rückgabe: Melanie
		System.out.println(benutzerDrei);//Rückgabe Steffen
		System.out.println(benutzerVier);//Rückgabe Sabine	
	}
}

Du kannst nämlich in Java einen String auch anlegen, ohne den Konstruktor aufzurufen.
Dazu weist du dem neuen String Objekt einfach einen Textwert zu.
Und fertig ist die Sache.

Aber….
Wo liegt der Unterschied?
Oder macht es überhaupt keinen Unterschied, wie du in Java Strings erstellst?

Java bietet dir nicht einfach aus purer Freude zwei Möglichkeiten an, Strings zu erstellen.

Das unterschiedliche Anlegen von String-Objekten hat weitreichende Konsequenzen.
Und zwar:

  • In der Performance deiner kompletten Java Anwendung
  • In der Sicherheit und Stabilität der kompletten Anwendung
  • Und auch im Vergleich der Strings untereinander.

Ich sagte bereits, Strings treten extrem häufig auf.
Und deshalb würdest du deine Programme extrem aufblähen, wenn du immer wieder komplett neue String Objekte anlegen würdest.

Java-Chatverlauf

Im Chatprogramm:
20 Nachrichten hin und her.
Und jedes Mal ein „Matze schrieb“ oder „Melanie schrieb“.
Würde bedeuten 20 Matze-String-Objekte und 20 Melanie-String-Objekte.

Klar du kannst immer wieder umswitchen.
Aber Java bietet intern schon eine bessere automatische Lösung.

Java Strings befinden sich entweder auf dem Heap oder im String Pool.

Zurück zum Code:


public class ChatProgramm {
	
	public static void main(String[] args) {
		String benutzerEins = new String ("Matze"); //neues String-Objekt über Konstruktor erstellt
		String benutzerZwei = new String ("Melanie");//neues String-Objekt über Konstruktor erstellt
		String benutzerDrei = "Steffen"; //neues String Objekt ohne Konstruktor
		String benutzerVier = "Sabine"; //noch ein Objekt ohne Konstruktor
		
		System.out.println(benutzerEins);//Rückgabe: Matze
		System.out.println(benutzerZwei);//Rückgabe: Melanie
		System.out.println(benutzerDrei);//Rückgabe Steffen
		System.out.println(benutzerVier);//Rückgabe Sabine	
	}
}

Matze und Melanie befinden sich auf dem Heap- der Speicherverwaltung für Java Objekte.

Doch wo sind Steffen und Sabine?
Auch auf dem Heap – aber in einem String-optimierten System.
Dem String Pool.

Java Strings Pool Verweise

Wenn ich jetzt einen fünften Benutzer anlege.
Und dieser heißt wieder Matze.
Und diesen lege ich über den Konstruktor an.
Dann landet Matze wieder auf dem Heap.
Java Strings Pool weiteres Objekt

Dann hast du zwei Matze-String-Objekte auf dem Heap.

Wenn ich aber noch einen Steffen, ohne Konstruktoraufruf anlege.
Dann landet kein neues Steffen-String-Objekt im String Pool.
Stattdessen verweisen jetzt zwei Referenzvariablen auf ein und dasselbe String-Objekt.

Java String Constant Pool

Das bedeutet, wenn ich alle Strings ohne einen Konstruktor anlege, kann ich mir ein Matze-Objekt, ein Steffen-Objekt, ein Sabine-Objekt und auch ein Melanie-String im String-Pool halten.


public class ChatProgramm {
	
	public static void main(String[] args) {
		String benutzerEins = "Matze"; 
		String benutzerZwei = "Matze";
		String benutzerDrei = "Matze";
		String benutzerVier = "Matze";
	}
}

Es verweisen sämtliche Referenzvariablen auf ein und daselbe Stringobjekt.

Java Strings Pool 4 Verweise 1 Objekt

Für unseren Chatverlauf würde dies bedeuten, dass jeder Benutzername nur einmal angelegt werden müsste.
Und bei jeder neuen Nachricht würde lediglich ein Verweis auf das String-Objekt im Pool erfolgen.

Was ist nun besser – Strings in den Pool lassen oder auf dem Objekte-Heap führen?
Natürlich ist immer der String Pool besser.
Erstelle deine Strings immer so:
String Referenzvariable = „Textwert“.

Natürlich kommt es vor, dass du das ein- oder andere String-Objekt auf dem Heap halten willst.
Aber dafür solltest du immer genau wissen – wieso.

Wenn du keine klare Strategie verfolgst – dann schieb den String immer in den Pool.

Jetzt stellt sich noch die Frage:

Wenn ich so viele unterschiedliche Matze-String-Variablen habe und diese alle nur auf ein dasselbe String-Objekt verweisen – Kommt das System damit überhaupt klar?

Bitte an dieser Stelle nicht mit Instanzvariablen verwechseln.
Es geht dabei nur um Ressourcenteilung.
Das Design einer Benutzerklasse für ein Chatprogramm würde so aussehen.

Java Strings Pool Instanzvariablen Verweis

  • Du hättest mehrere Benutzer-Objekte.
  • Alle Benutzerobjekte hätten individuelle Instanzvariablen, wie das Alter, Profilbild und auch den Namen.
  • Der Name wäre dann nur eine von vielen möglichen Instanzvariablen.
  • Und da vielleicht manche der Nutzer den gleichen Namen haben, teilt man sich die Ressource.

Eins noch.
Bereits bestehende String-Objekte kannst du über die intern-Methode in den Pool verschieben.
Und so gehts.


public class ChatProgramm {
	
	public static void main(String[] args) {
		String benutzerEins = new String ("Matze");
		
		benutzerEins=benutzerEins.intern();//wird in den String Pool verschoben
	}
}

Zusammenfassung:

  • Du kannst Java Strings auf zwei unterschiedliche Arten anlegen.
  • Einmal über den Konstruktoraufruf.
    Dabei werden Objekte direkt auf den Heap erzeugt und dort verwaltet.
  • Oder du legst String-Objekte ohne Konstruktoraufruf an und dann werden diese in einem String-Pool verwaltet.
  • Der Vorteil der zweiten Methode besteht darin, dass Java selbstständig prüft, ob bereits ein String mit diesem identischen Textwert existiert.
    Und dann verweist Java automatisch die neue Referenzvariable zum bereits vorhandenen Stringobjekt.

Ähnliche Beiträge

3 Möglichkeiten um Vererbung von Java Klassen zu verhindern, zu verbieten oder ausschließen

Java Vererbung verhindern

Die ganze Java Vererbung für bestimmte Klassen ausschließen bzw. verhindern oder verbieten. Was soll das? Für bestimmte Java Klassen soll die Vererbung ausgeschlossen werden. Es soll also verhindert werden, dass Elternklassen – Kindklassen bekommen können. Klingt ein bisschen wie Verhütung, oder? Denn wie auch im echten Leben, können Kinder zu kleinen Tyrannen werden. Sie bedienen […]

Java Übung 26 – Das erste kleine Java Spiel

Java Übung Zahlenraten

In dieser Java Übung geht es darum ein kleines Java-Spiel zu erstellen. Und zwar Zahlen raten. Was kannst du dir darunter vorstellen? Du gibst einen bestimmten Wertebereich an. Zum Beispiel 0 bis 100. Und das Java Programm erstellt eine Zufallszahl in diesem Bereich. Dann fordert dich das Programm auf, die Zahl zu raten. Du gibst […]

Die mathematischen Grundlagen des Dezimalsystems für Java Programmierer

Java Dezimalsystem Mathematik Programmierer

Bei der Java Programmierung benötigst du Kenntnisse über das Dezimalsystem. Allein schon für die technische Umsetzung beim Runden einer Zahl. Oder du möchtest den Kehrwert bzw. den Umkehrwert einer Zahl im Programm bestimmen lassen. Aber auch für das Herausfinden des Stellenwertes – also wieviel Stellen hat eine Zahl – benötigst du das Grundwissen des Dezimalsystems. […]

Java Übung 11 – Java Objekte in Java Methoden übergeben

Java Übung Java Methoden Objekte

In dieser Java Übung möchte ich dir zeigen, dass du auch in Klassenmethoden auf Objekte und deren Instanzvariablen zugreifen kannst. Schau dir dazu einmal diesen Java Code an. public class Umwandlung { private int x; public int getX() { // getter Methode return x; } public void setX(int x) { // setter Methode this.x = […]

Nutze das Keyword this für deine Java Konstruktoren

Java konstruktoren this

Es ist gemein. Wahrscheinlich hast den Beitrag zu den lokalen Variablen gelesen. Vielleicht hast du auch den Artikeln zum Anlegen und Überladen von Java Konstruktoren gelesen. Und wenn du die beschriebene Inhalte selbst ausprobiert hast…… Dann hast du dir wahrscheinlich sehr viele lokale Variablennamen für die Parameterliste ausdenken müssen.

Java Duales Zahlensystem – Binäre Zahlen in Java umwandeln

Java Dual System

Das duale Zahlensystem hat viele Bezeichnungen. Oft wird auch es Dualsystem oder Binärsystem genannt. Es besteht aber immer aus 2 Zahlen. Man verwendet oft die Zahlen 0 und 1. Es können aber auch sämtliche anderen Zahlenpaare sein. Zum Beispiel 7 und 175 sind für sich genommen, auch ein normales Zahlenpaar und somit ein Dualsystem. Mit […]

Java Übung 27 – Auf zur Mathe-Olympiade

Java Übung Mathe Olympiade

In dieser Java Übung möchte ich mit dir ein Programm erstellen, welches ein Mathematik-Test oder eine Mathe-Olympiade simuliert. Du kennst das vielleicht noch aus der Schule. Matheolympiade- Da wurden aus allen vier Grundrechenarten, Aufgaben formuliert. Die Schüler mussten diese Aufgaben lösen. Die Lehrer kontrollierten die Lösungen. Und der Schüler, welcher die wenigsten Fehler hatte – […]

Java Übung 24 – So kannst du Kommazahlen runden

Java Übung runden

In dieser Java Übung möchte ich mit dir Zahlen runden. Ich bitte dich deshalb: Erstelle eine Klasse „RundenUebung“. Lege dann eine statische Methode rundeZahl() an. Diese erwartet zwei Parameter. Parameter 1 ist die Kommazahl, welche gerundet werden soll. Als zweiten Parameter wird eine ganze Zahl übergeben, welche die Nachkommastelle – bis auf welche letztlich gerundet […]

So lassen sich Java Arrays kopieren

Java Arrays kopieren

Java Arrays kopieren oder klonen…. Was heißt das eigentlich? Eine Kopie ist eine Reproduktion bzw. die Nachbildung eines Originals. Somit ist jede Fotographie – die Abbildung einer bestimmten optischen Wirklichkeit, zu einem festen Zeitpunkt. Die Kopie einer Buchseite ist das optische Abbild dieser spezifischen Buchseite – auch zu einem festen Zeitpunkt. Wichtig in diesem Zusammenhang […]

So kannst du gelöschte Java Projekte oder Dateien in Eclipse wieder herstellen

Wahrscheinlich passiert es jedem einmal, dass man versehentlich Dateien löscht. Und dann? Die Wut ist riesig, weil man ja alles nochmal schreiben muss. In Eclipse hast du die Möglichkeit sämtliche Dateien wieder herzustellen. In diesem Beitrag möchte ich dir demonstrieren, wie du gelöschte Java Klassen, Dateien, Projekte oder Packages wieder herstellen kannst.

Drei Möglichkeiten um Java Objekte zu zerstören

Java Objekte zerstören

Java Objekte leben genau solange, wie eine Referenzvariable auf sie zeigt. Wenn dieser Zeiger nicht mehr existiert, wird dieses Objekt aufgeben. Und wenn dieses Objekt erst einmal aufgegeben wurde, dann kommt der Garbage Collector und entsorgt dieses. Aber wie kannst du nun am Sinnvollsten Objekte aufgeben? Lass es uns herausfinden.

Java Exklusives Oder – So nutzt du den Xor Operator

Java exklusives oder

In diesem Beitrag möchte ich dir den Xor Operator von Java vorstellen. Dieser Operator wird auch als ausschließendes oder exklusives Oder bezeichnet. Ein Beispiel: Was wilst du heute zum Mittag essen: Fleisch oder Fisch? Auf diese Frage gibt es nur eine Antwort. Es ist entweder Fisch oder Fleisch. Niemals beides. Das Eine schließt das andere […]