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

## 11.3 Weitere Eigenschaften

- 11.3 Weitere Eigenschaften
  - 11.3.1 Die Klasse String ist final
  - 11.3.2 Was ist ein String für den Compiler?
    - String-Literale
    - String-Verkettung und -Zuweisung
  - 11.3.3 String-Objekte sind nicht dynamisch

### 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
<< | < | > | >> | API | © 1998-2002 Guido Krüger, http://www.javabuch.de