Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 3. Auflage
 <<    <     >    >>   API  Kapitel 11 - Strings

11.3 Weitere Eigenschaften



11.3.1 Die Klasse String ist final

Beim Studium der Klassenbibliotheken erkennt man, daß die Klasse String mit dem Attribut final belegt ist. Einer der Gründe für diese Maßnahme ist die dadurch gesteigerte Effizienz beim Aufruf der Methoden von String-Objekten. Anstelle der dynamischen Methodensuche, die normalerweise erforderlich ist, kann der Compiler final-Methoden statisch kompilieren und dadurch schneller aufrufen. Daneben spielten aber auch Sicherheitsüberlegungen und Aspekte des Multithreadings eine Rolle.

Leider hat dies den großen Nachteil, daß aus der String-Klasse keine neuen Klassen abgeleitet werden können. Es gibt also keine Möglichkeit, die vorhandenen Methoden auf natürliche Art und Weise zu ergänzen oder zu modifizieren. Soll beispielsweise eine neue Methode replace geschrieben werden, die in der Lage ist, Strings (und nicht nur einzelne Zeichen) gegeneinander auszutauschen, so bleibt nur der Umweg über eine Methode einer anderen Klasse, die den zu modifizierenden String als Parameter übergeben bekommt. Alternativ könnte man natürlich auch die komplette String-Klasse neu schreiben. Leider sind beide Varianten unschön und konterkarieren die Vorteile der objektorientierten Implementierung von Zeichenketten in Java.

 Hinweis 

11.3.2 Was ist ein String für den Compiler?

In Java gibt es an vielen Stellen Verbindungen zwischen dem Compiler und der Laufzeitbibliothek, und zwar insofern, als der Compiler Kenntnis über interne Eigenschaften bestimmter Klassen hat und die Fähigkeit besitzt, Instanzen dieser Klassen zu erzeugen und zu manipulieren. So ist er beispielsweise in der Lage, Code zu generieren, um String-Objekte zu erzeugen, einander zuzuweisen oder mit Hilfe des +-Operators zu verketten.

String-Literale

Jedes String-Literal ist eine Referenz auf ein Objekt der Klasse String. Wenn der Compiler beim Übersetzen des Quelltextes ein String-Literal findet, erzeugt er ein neues String-Objekt und verwendet es anstelle des Literals.

String-Verkettung und -Zuweisung

In Java ist der Operator + auch auf Strings definiert. Auf zwei String-Objekte angewendet, liefert er die Verkettung beider Objekte, d.h. ihre Hintereinanderschreibung. Eine Möglichkeit, die String-Verkettung zu übersetzen, könnte darin bestehen, ein temporäres StringBuffer-Objekt zu konstruieren und die Operanden mit Hilfe der append-Methode anzuhängen. Das resultierende Objekt könnte dann mit der toString-Methode effizient in einen String konvertiert werden. Die Klasse StringBuffer dient dazu, veränderliche Strings zu implementieren. Sie wird im nächsten Abschnitt vorgestellt.

Diese Vorgehensweise soll an dem folgenden Beispiel erläutert werden. Das Programm gibt zweimal hintereinander »Hallo, Welt« aus. Beim ersten Mal wird der +-Operator verwendet, beim zweiten Mal die Variante mit dem temporären StringBuffer-Objekt:

001 /* Listing1103.java */
002 
003 public class Listing1103
004 {
005   public static void main(String[] args)
006   {
007     String a, b, c;
008 
009     //Konventionelle Verkettung
010     a = "Hallo";
011     b = "Welt";
012     c = a + ", " + b;
013     System.out.println(c);
014 
015     //So könnte es der Compiler übersetzen
016     a = "Hallo";
017     b = "Welt";
018     c =(new StringBuffer(a)).append(", ").append(b).toString();
019     System.out.println(c);
020   }
021 }
Listing1103.java
Listing 11.3: Implementierung der String-Verkettung

Allerdings ist ein Java-Compiler nicht gezwungen, genau so vorzugehen. Die Sprachspezifikation gibt lediglich die Empfehlung, daß es aus Effizienzgründen sinnvoll sein kann, eine solche oder ähnliche Implementierung zu wählen.

11.3.3 String-Objekte sind nicht dynamisch

Interessanterweise werden durch die Klasse String keine dynamischen Zeichenketten implementiert. Nach der Initialisierung eines String bleiben dessen Länge und Inhalt konstant. Wie ist dann aber die genaue Arbeitsweise von Funktionen wie substring oder replace zu erklären, und was genau passiert bei einer Anweisung wie der folgenden:

String s = "hello, world";
s = s.substring(0,5);

Die Antwort darauf ist ganz einfach. Die substring-Methode nimmt die Veränderungen nicht auf dem Original-String vor, sondern erzeugt eine Kopie, die mit dem gewünschten Inhalt gefüllt wird. Diese gibt sie dann an den Aufrufer zurück, der das Ergebnis erneut an s zuweist und damit die Originalinstanz für den Garbage Collector freigibt. Durch den Referenzcharakter von Objekten und das automatische Speichermanagement entsteht also der Eindruck, als wären String-Objekte veränderlich.

Als Entwickler braucht man sich hierüber normalerweise keine Gedanken zu machen. Dennoch ist es manchmal nützlich, Zeichenketten zur Verfügung zu haben, die sich dynamisch verändern können (beispielsweise benötigt sie der Compiler selbst zur Implementierung der String-Verkettung). In Java gibt es zu diesem Zweck die Klasse StringBuffer. Sie arbeitet ähnlich wie String, implementiert aber Zeichenketten, die ihre Länge zur Laufzeit ändern können. StringBuffer besitzt nicht so viele Methoden zur Auswertung der Zeichenkette, sondern legt den Schwerpunkt auf Operationen zur Veränderung ihres Inhalts. Die wichtigsten Methoden sollen im folgenden vorgestellt werden.


 Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 3. Auflage, Addison Wesley, Version 3.0.1
 <<    <     >    >>   API  © 1998-2003 Guido Krüger, http://www.javabuch.de