© Excellent backgrounds/Shutterstock.com
Speicherallokation im Laufe der Java-Versionen

String und Substring


Java 7 hat die Struktur von Strings heimlich, still und leise verändert. Anstelle von offset und count beinhaltet der String nur noch char[]. Das hat einige negative Auswirkungen auf jene, die erwarten, substring() würde immer das darunterliegende char[] teilen.

String ist in Java-Programmen allgegenwärtig. Er hat sich über die Java-Generationen hinweg auf verschiedenen Ebenen verändert. In sehr frühen Versionen z. B. hätte der generierte Code aus der Verkettung nicht konstanter Strings entweder concat() oder StringBuffer ergeben können. In Java 1.0 und 1.1 hätte die Methode hashCode() die Größe des Strings überprüft. Wäre er zu lang gewesen, hätte sich jedes achte Zeichen statt jedes einzelnen addiert. Angesichts des Speicherlayouts wirkt diese Optimierung ohnehin nicht besonders effizient. Unter Java 2 änderte sich das Prinzip zu „jedes Zeichen immer“, und unter Java 3 wurde der HashCode zwischengespeichert.

Die Liste der Wünsche klingt vernünftig, nicht wahr? Es gibt fast keine Fälle in realem Code, bei denen uns das Prinzip weiterhilft. Wir gehen davon aus, dass es unwahrscheinlich ist, der HashCode sei gleich null. Stimmt’s? Wer einmal eine Zeichenkette gefunden hat, deren HashCode gleich null ist, kann eine beliebig lange Serie generieren. Eine konstante Zeitoperation wie hashCode(), die gecachte Werte nutzt, wird jetzt potenziell zu O(n). Im Zusammenhang mit Java 7 wurde versucht, die hash32()-Berechnung zu fixen. Das würde einen Nullwert ausschließen. Allerdings ist es in Java 8 auch wieder verschwunden.

Kürzlich haben mein Co-Trainer Maurice Naftalin (der Mann hinter Mastering Lambdas) und ich unseren Extreme-Java-8-Kurs gehalten, der sich auf Concurrency und Performance konzentriert. Ich räume dem Thema String immer etwas Zeit ein, da es häufig verwendet wird und dazu tendiert, die Spitze des Eisbergs vieler Probleme zu sein. Von Java 1.0 bis 1.6 versuchte String zu vermeiden, neue Zeichenarrays (char[]) anlegen zu müssen. Die substring()-Methode würde dasselbe darunter liegende char[] teilen, mit anderem Offset und anderer Länge. In StringChars haben wir z. B. zwei Strings, mit hello einen Substring von hello_world. Die beiden teilen sich jedoch das gleiche Zeichenarray (Listing 1). Von Java 1 bis einschließlich Java 6 sähen wir diesen Output:

Hello [C@721cdeff [C@721cdeff

Listing 1

import java.lang.reflect.*; public class StringChars { public static void main(String... args) throws NoSuchFieldException, IllegalAccessException { Field value...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang