Warum ist String in Java unveränderlich?

Warum ist String in Java unveränderlich?

1. Einführung

In Java sind Strings unveränderlich. Eine naheliegende Frage, die in Interviews häufig gestellt wird, lautet: "Warum sind Strings in Java unveränderlich?"

James Gosling, der Schöpfer von Java,was once asked in an interview wann sollte man unveränderliche verwenden, worauf er antwortet:

Ich würde eine unveränderliche verwenden, wann immer ich kann.

Er stützt seine Argumentation ferner auf Merkmale, die Unveränderlichkeit bietet, wie z. B. Zwischenspeicherung, Sicherheit, einfache Wiederverwendung ohne Replikation usw.

In diesem Tutorial werden wir weiter untersuchen, warum die Java-Sprachdesigner beschlossen haben,Stringunveränderlich zu halten.

2. Was ist ein unveränderliches Objekt?

Ein unveränderliches Objekt ist einobject whose internal state remains constant after it has been entirely created. Dies bedeutet, dass wir nach der Zuweisung des Objekts zu einer Variablen weder die Referenz aktualisieren noch den internen Zustand auf irgendeine Weise verändern können.

Wir haben einen separaten Artikel, der unveränderliche Objekte ausführlich behandelt. Weitere Informationen finden Sie im ArtikelImmutable Objects in Java.

3. Warum istStringin Java unveränderlich?

Die wichtigsten Vorteile dieser unveränderlichen Klasse sind Caching, Sicherheit, Synchronisierung und Leistung.

Lassen Sie uns diskutieren, wie diese Dinge funktionieren.

3.1. InString Pool einführen

String ist die am häufigsten verwendete Datenstruktur. Das Zwischenspeichern derString-Literale und deren Wiederverwendung spart viel Heap-Speicherplatz, da verschiedeneString-Variablen auf dasselbe Objekt imString-Pool verweisen. Der interne Pool vonStringdient genau diesem Zweck.

Der Java-String-Pool istthe special memory region where Strings are stored by the JVM. DaStrings in Java unveränderlich sind, optimiert die JVM die für sie zugewiesene Speichermenge, indem nur eine Kopie jedes LiteralString im Pool gespeichert wird. Diesen Vorgang nennt man Internierung:

String s1 = "Hello World";
String s2 = "Hello World";

assertThat(s1 == s2).isTrue();

Aufgrund des Vorhandenseins des PoolsStringim vorhergehenden Beispiel zeigen zwei verschiedene Variablen auf dasselbe ObjektStringaus dem Pool, wodurch wichtige Speicherressourcen gespart werden.

image

Wir haben einen separaten Artikel über den JavaString-Pool. Für weitere Informationenhead on over to that article.

3.2. Sicherheit

String wird in Java-Anwendungen häufig zum Speichern vertraulicher Informationen wie Benutzernamen, Kennwörter, Verbindungs-URLs, Netzwerkverbindungen usw. verwendet. Es wird auch häufig von JVM-Klassenladeprogrammen beim Laden von Klassen verwendet.

Daher ist die Sicherung der KlasseStringfür die Sicherheit der gesamten Anwendung im Allgemeinen von entscheidender Bedeutung. Betrachten Sie beispielsweise diesen einfachen Codeausschnitt:

void criticalMethod(String userName) {
    // perform security checks
    if (!isAlphaNumeric(userName)) {
        throw new SecurityException();
    }

    // do some secondary tasks
    initializeDatabase();

    // critical task
    connection.executeUpdate("UPDATE Customers SET Status = 'Active' " +
      " WHERE UserName = '" + userName + "'");
}

Nehmen wir im obigen Codefragment an, dass wir einString-Objekt von einer nicht vertrauenswürdigen Quelle erhalten haben. Wir führen zunächst alle erforderlichen Sicherheitsüberprüfungen durch, um zu überprüfen, obString nur alphanumerisch ist, gefolgt von einigen weiteren Vorgängen.

Denken Sie daran, dass unsere unzuverlässige Quellaufrufmethode immer noch auf das ObjektuserNameverweist.

If Strings were mutable, then by the time we execute the update, we can’t be sure that the String we received, even after performing security checks, would be safe. Die nicht vertrauenswürdige Aufrufermethode verfügt weiterhin über die Referenz und kann dieString zwischen Integritätsprüfungen ändern. Daher ist unsere Abfrage in diesem Fall anfällig für SQL-Injections. VeränderbareStrings können daher im Laufe der Zeit zu einer Verschlechterung der Sicherheit führen.

Es kann auch vorkommen, dassStringuserName für einen anderen Thread sichtbar ist, der dann nach der Integritätsprüfung seinen Wert ändern kann.

Im Allgemeinen hilft uns die Unveränderlichkeit in diesem Fall, da es einfacher ist, mit vertraulichem Code zu arbeiten, wenn sich die Werte nicht ändern, da weniger Verschachtelungen von Vorgängen das Ergebnis beeinflussen können.

3.3. Synchronisation

Wenn Sie unveränderlich sind, ist der Thread vonStringautomatisch sicher, da er beim Zugriff von mehreren Threads nicht geändert wird.

Daherimmutable objects, in general, can be shared across multiple threads running simultaneously. They’re also thread-safe, denn wenn ein Thread den Wert ändert, wird anstelle des gleichen Wertes ein neuerString im Pool vonString erstellt. Daher sindStrings für Multithreading sicher.

3.4. Hashcode-Caching

DaString Objekte häufig als Datenstruktur verwendet werden, werden sie auch häufig in Hash-Implementierungen wieHashMap,HashTable,HashSet usw. verwendet. Wenn Sie mit diesen Hash-Implementierungen arbeiten, wird die MethodehashCode()ziemlich häufig zum Bucketing aufgerufen.

Die Unveränderlichkeit garantiertStrings, dass sich ihr Wert nicht ändert. Alsothe hashCode() method is overridden in String class to facilitate caching, such that the hash is calculated and cached during the first hashCode() call and the same value is returned ever since.

Dies wiederum verbessert die Leistung von Sammlungen, die Hash-Implementierungen verwenden, wenn sie mitString-Objekten betrieben werden.

Andererseits würden veränderbareStrings zum Zeitpunkt des Einfügens und Abrufens zwei verschiedene Hashcodes erzeugen, wenn der Inhalt vonString nach der Operation geändert würde, wodurch möglicherweise das Wertobjekt inMap verloren gehen würde.

3.5. Performance

Wie wir zuvor gesehen haben, existiert der Pool vonString, weilStrings unveränderlich sind. Dies wiederum verbessert die Leistung, indem es Heapspeicher spart und schneller auf Hash-Implementierungen zugreift, wenn es mitStrings. betrieben wird

DaString die am häufigsten verwendete Datenstruktur ist, hat die Verbesserung der Leistung vonString einen erheblichen Einfluss auf die Verbesserung der Leistung der gesamten Anwendung im Allgemeinen.

4. Fazit

Durch diesen Artikel können wir schließen, dassStrings are immutable precisely so that their references can be treated as a normal variable and one can pass them around, between methods and across threads, without worrying about whether the actual String object it’s pointing to will change.

Wir haben auch gelernt, was die anderen Gründe sein könnten, die die Sprachdesigner vonJavadazu veranlasst haben, diese Klasse als unveränderlich zu betrachten.