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.Stringwar nicht endgültig, SafeStringkönnte a gleich a seinString und umgekehrt; weil sie die gleiche Folge von Zeichen darstellen würden.
Was würde passieren, wenn Sie sich internbei a bewerben SafeStringwürden - würde das SafeStringin den String-Pool der JVM gehen? Die ClassLoaderund alle Objekte, auf die SafeStringdie 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 SafeStringwürden Sie gewinnen, vielleicht eine Stringoder 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! = StringThen SafeString.intern! = String.internUnd SafeStringzum 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.