Es gibt wirklich zwei Fragen hier:
- Sind Zeichenfolgen wirklich unveränderlich?
- Warum wird s3 nicht geändert?
Zu Punkt 1: Mit Ausnahme von ROM gibt es keinen unveränderlichen Speicher in Ihrem Computer. Heutzutage ist sogar ROM manchmal beschreibbar. Irgendwo gibt es immer einen Code (ob es sich um den Kernel oder nativen Code handelt, der Ihre verwaltete Umgebung umgeht), der an Ihre Speicheradresse schreiben kann. Also sind sie in "Wirklichkeit" nicht absolut unveränderlich.
Zu Punkt 2: Dies liegt wahrscheinlich daran, dass das Teilzeichenfolge wahrscheinlich eine neue Zeichenfolgeninstanz zuweist, die wahrscheinlich das Array kopiert. Es ist möglich, das Teilzeichenfolge auf eine Weise implementiert ist, dass es keine Kopie erstellt, aber das bedeutet nicht, dass es so ist. Es gibt Kompromisse.
Zum Beispiel, sollte das Halten eines Verweises auf wirklichGrosseZeichenkette.teilzeichenkette(wirklichGrosseZeichenkette.länge - 2)
eine große Menge an Speicher am Leben erhalten oder nur wenige Bytes?
Das hängt davon ab, wie die Teilzeichenfolge implementiert ist. Eine tiefe Kopie hält weniger Speicher am Leben, läuft aber etwas langsamer. Eine flache Kopie hält mehr Speicher am Leben, ist aber schneller. Die Verwendung einer tiefen Kopie kann auch die Fragmentierung des Heaps reduzieren, da das Zeichenfolgenobjekt und sein Puffer in einem Block zugewiesen werden können, im Gegensatz zu 2 separaten Heap-Zuweisungen.
In jedem Fall scheint Ihr JVM sich entschieden zu haben, tiefe Kopien für Teilzeichenfolgenaufrufe zu verwenden.