Warum sind Strings in Java "Immutable"?

Eine der grundlegenden Eigenschaften von Strings in Java ist ihre Unveränderlichkeit, auch bekannt als Immutability. Doch was genau bedeutet es, dass Strings unveränderlich sind, und welche Vorteile bringt diese Eigenschaft mit sich? Mehr in diesem Artikel.

Thread-Sicherheit

Strings werden häufig in Umgebungen mit mehreren Threads verwendet, und das sie eben "Immutable" sind, macht sie das auch thread-sicher, da der Wert eines Strings nicht von einem Thread geändert werden kann, während er von einem anderen verwendet wird.

Speichereffizienz

Java verwendet eine Technik namens String-Interning (oder Java String Pool), die eine effiziente Speichernutzung durch Wiederverwendung identischer String-Werte ermöglicht: In dem Heap-Speicher wird ein Pool von Strings verwaltet in dem alle Strings gespeichert werden, die mit String-Literalen erstellt werden. Die JVM verwaltet eine einzige Kopie jedes String-Literales in diesem String-Pool, um den Speicherverbrauch zu verringern. Wenn ein Stringliteral erstellt wird, prüft die JVM, ob ein String mit demselben Wert bereits im Pool vorhanden ist. Ist dies der Fall, gibt sie einen Verweis auf die vorhandene Zeichenkette zurück, anstatt eine neue zu erstellen.

Zudem ermöglicht die Unveränderlichkeit von Strings die Verwendung von Strings als Schlüssel in Maps und als Elemente in Sets. Da sich der Wert eines Schlüssels oder Elements nicht ändert, können sie effizient in den entsprechenden Datenstrukturen verwendet werden.

Strings und die Verwendung von "equals"

String str1 = "jberries";       // String literal, nutzt string pool
String str2 = "jberries";       // Reuses "jberries" aus dem string pool
String str3 = new String("jberries"); // Erstellt ein neues Objekt auf dem Heap

// Vergleich mit "=="
System.out.println(str1 == str2); // true, da beide auf dasselbe Objekt im Pool verweisen
System.out.println(str1 == str3); // false, da str3 ein neues Objekt ist

// Vergleich mit equals()
System.out.println(str1.equals(str2)); // true, da die Werte gleich sind
System.out.println(str1.equals(str3)); // true, da die Werte gleich sind

Sicherheit

Da Strings nach der Erstellung nicht mehr geändert werden können, eignen sie sich für sensible Daten wie zB. Passwörter: Wären String nicht "Immutable", dann könnte man zum Beispiel beim Aufruf einer externen Bibliothek zur Passwort-Validierung nicht sicher sein, dass das Passwort in dieser Bibliothek unverändert bleibt.

Die Unveränderlichkeit von Strings hat jedoch auch einige Nachteile. Wenn ein String verändert wird, wird tatsächlich ein neues String-Objekt erstellt, was zu einem erhöhten Speicherbedarf und Performance-Problemen führen kann.

Um die Nachteile der String-Konkatenation zu umgehen, empfiehlt es sich, die Klasse StringBuilder (nicht thread-safe) oder StringBuffer (langsamer aber thread-safe) zu verwenden.