Dies ist ein schöner Artikel , der zwei Gründe umreißt, die bereits in den obigen Antworten erwähnt wurden:
- Sicherheit : Das System kann vertrauliche schreibgeschützte Informationen weitergeben, ohne befürchten zu müssen, dass sie geändert werden
- Leistung : Unveränderliche Daten sind sehr nützlich, um die Sicherheit von Threads zu gewährleisten.
Und dies ist wahrscheinlich der ausführlichste Kommentar in diesem Artikel. Dies hat mit dem String-Pool in Java und Sicherheitsproblemen zu tun. Es geht darum, wie man entscheidet, was in den String-Pool geht. Angenommen, beide Zeichenfolgen sind gleich, wenn ihre Zeichenfolge gleich ist, dann haben wir eine Race-Bedingung, wer zuerst dort ankommt und damit Sicherheitsprobleme. Wenn nicht, enthält der Zeichenfolgenpool redundante Zeichenfolgen, wodurch der Vorteil verloren geht, dass er überhaupt vorhanden ist. Lesen Sie es einfach selbst vor, oder?
Das Erweitern des Strings würde mit Gleichen und Praktikanten Chaos anrichten. JavaDoc sagt gleich:
Vergleicht diese Zeichenfolge mit dem angegebenen Objekt. Das Ergebnis ist genau dann wahr, wenn das Argument nicht null ist und ein String-Objekt ist, das dieselbe Zeichenfolge wie dieses Objekt darstellt.
Vorausgesetzt, es java.lang.String
war nicht endgültig, SafeString
könnte a gleich a seinString
und umgekehrt; weil sie die gleiche Folge von Zeichen darstellen würden.
Was würde passieren, wenn Sie sich intern
bei a bewerben SafeString
würden - würde das SafeString
in den String-Pool der JVM gehen? Die ClassLoader
und alle Objekte, auf die SafeString
die Referenzen verweisen, werden dann für die Lebensdauer der JVM an Ort und Stelle gesperrt. Sie würden eine Rennbedingung darüber erhalten, wer als erster eine Folge von Charakteren internieren könnte - vielleicht SafeString
würden Sie gewinnen, vielleicht eine String
oder vielleicht eineSafeString
von einem anderen Klassenlader geladene (also eine andere Klasse).
Wenn Sie das Rennen in den Pool gewinnen würden, wäre dies ein echter Singleton und die Leute könnten durch Reflexion und auf Ihre gesamte Umgebung (Sandbox) zugreifen secretKey.intern().getClass().getClassLoader()
.
Oder die JVM könnte dieses Loch blockieren, indem sie sicherstellt, dass nur konkrete String-Objekte (und keine Unterklassen) zum Pool hinzugefügt wurden.
Wenn equals so implementiert wurde, dass SafeString
! = String
Then SafeString.intern
! = String.intern
Und SafeString
zum Pool hinzugefügt werden müsste. Der Pool würde dann zu einem Pool von <Class, String>
statt <String>
und alles, was Sie brauchen, um den Pool zu betreten, wäre ein frischer Klassenlader.