Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 3. Auflage
<< | < | > | >> | API | Kapitel 5 - Ausdrücke

## 5.7 Sonstige Operatoren

- 5.7 Sonstige Operatoren
  - 5.7.1 Weitere Operatoren für primitive Typen
    - Fragezeichenoperator
    - Type-Cast-Operator
  - 5.7.2 Operatoren für Objekte
    - String-Verkettung
    - Referenzgleichheit und -ungleichheit
    - Der instanceof-Operator
    - Der new-Operator
    - Member-Zugriff
    - Methodenaufruf
    - Zugriff auf Array-Elemente
  - 5.7.3 Welche Operatoren es nicht gibt

Neben den bisher vorgestellten Operatoren stellt Java noch eine Reihe weiterer Operatoren zur Verfügung, die in diesem Abschnitt erläutert werden sollen.

### 5.7.1 Weitere Operatoren für primitive Typen

#### Fragezeichenoperator

Der Fragezeichenoperator `?:` ist der einzige dreistellige Operator in Java. Er erwartet einen logischen Ausdruck und zwei weitere Ausdrücke, die beide entweder numerisch, von einem Referenztyp oder vom Typ `boolean` sind.

Bei der Auswertung wird zunächst der Wert des logischen Operators ermittelt. Ist dieser wahr, so wird der erste der beiden anderen Operanden ausgewertet, sonst der zweite. Das Ergebnis des Ausdrucks `a ? b : c` ist also `b`, falls `a` wahr ist, und `c`, falls `a` falsch ist. Der Typ des Rückgabewerts entspricht dem Typ des größeren der beiden Ausdrücke `a` und `b`.

#### Type-Cast-Operator

Ebenso wie in C gibt es auch in Java einen Type-Cast-Operator, mit dessen Hilfe explizite Typumwandlungen vorgenommen werden können. Der Ausdruck `(type) a` wandelt den Ausdruck `a` in einen Ausdruck vom Typ `type` um. Auch wenn `a` eine Variable ist, ist das Ergebnis von `(type) a` ein Ausdruck, der nicht mehr auf der linken, sondern nur noch auf der rechten Seite eines Zuweisungsoperators stehen darf.

Wie in Kapitel 4 erklärt, gibt es verschiedene Arten von Typkonvertierungen in Java. Mit Hilfe des Type-Cast-Operators dürfen alle legalen Typkonvertierungen vorgenommen werden. Der Type-Cast-Operator wird vor allem dann angewendet, wenn der Compiler keine impliziten Konvertierungen vornimmt; beispielsweise bei der Zuweisung von größeren an kleinere numerische Typen oder bei der Umwandlung von Objekttypen.

### 5.7.2 Operatoren für Objekte

|  | Es gibt in Java einige Ausdrücke und Operatoren, die mit Objekten arbeiten oder Objekte produzieren. Die meisten von ihnen können erst dann erläutert werden, wenn die entsprechenden Konzepte in späteren Kapiteln eingeführt wurden. Der Vollständigkeit halber sollen sie dennoch an dieser Stelle erwähnt werden. |  |
Hinweis

#### String-Verkettung

Der `+`-Operator kann nicht nur mit numerischen Operanden verwendet werden, sondern auch zur Verkettung von Strings. Ist wenigstens einer der beiden Operatoren in `a + b` ein String, so wird der gesamte Ausdruck als String-Verkettung ausgeführt. Hierzu wird gegebenenfalls zunächst der Nicht-String-Operand in einen String umgewandelt und anschließend mit dem anderen Operanden verkettet. Das Ergebnis der Operation ist wieder ein String, in dem beide Operanden hintereinanderstehen.

|  |  |  | In Java ist die Konvertierung in einen String für nahezu jeden Typen definiert. Bei primitiven Typen wird die Umwandlung vom Compiler und bei Referenztypen durch die Methode `toString` ausgeführt. Die String-Verkettung ist daher sehr universell zu verwenden und ermöglicht (beispielsweise zu Ausgabezwecken) eine sehr bequeme Zusammenfassung von Ausdrücken unterschiedlichen Typs. Ein typisches Beispiel für die Verwendung der String-Verkettung ist die Ausgabe von numerischen Ergebnissen auf dem Bildschirm: |  |
Tip

    001 /* Listing0503.java */
    002
    003 public class Listing0503
    004 {
    005   public static void main(String[] args)
    006   {
    007     int a = 5;
    008     double x = 3.14;
    009
    010     System.out.println("a = " + a);
    011     System.out.println("x = " + x);
    012   }
    013 }
| Listing0503.java

Listing 5.3: String-Verkettung

Die Ausgabe des Programms lautet:

    a = 5
    x = 3.14

|  |  |  | Etwas Vorsicht ist geboten, wenn sowohl String-Verkettung als auch Addition in einem Ausdruck verwendet werden sollen, da die in diesem Fall geltenden Vorrang- und Assoziativitätsregeln zu unerwarteten Ergebnissen führen können. Das folgende Programm gibt daher nicht `3 + 4 = 7`, sondern `3 + 4 = 34` aus. |  |
Warnung

    001 /* Listing0504.java */
    002
    003 public class Listing0504
    004 {
    005   public static void main(String[] args)
    006   {
    007     System.out.println("3 + 4 = " + 3 + 4);
    008   }
    009 }
| Listing0504.java

Listing 5.4: Vorsicht bei der String-Verkettung!

Um das gewünschte Ergebnis zu erzielen, müßte der Teilausdruck `3 + 4` geklammert werden:

    001 /* Listing0505.java */
    002
    003 public class Listing0505
    004 {
    005   public static void main(String[] args)
    006   {
    007     System.out.println("3 + 4 = " + (3 + 4));
    008   }
    009 }
| Listing0505.java

Listing 5.5: Korrekte String-Verkettung bei gemischten Ausdrücken

#### Referenzgleichheit und -ungleichheit

|  | Die Operatoren `==` und `!=` können auch auf Objekte, also auf Referenztypen, angewendet werden. In diesem Fall ist zu beachten, daß dabei lediglich die Gleichheit oder Ungleichheit der Referenz getestet wird. Es wird also überprüft, ob die Objektzeiger auf ein und dasselbe Objekt zeigen, und nicht, ob die Objekte inhaltlich übereinstimmen. |  |
Hinweis

Ein einfaches Beispiel ist der Vergleich zweier Strings `a` und `b`, die beide den Inhalt "hallo" haben:

    001 /* Listing0506.java */
    002
    003 public class Listing0506
    004 {
    005   public static void main(String[] args)
    006   {
    007     String a = new String("hallo");
    008     String b = new String("hallo");
    009     System.out.println("a == b liefert " + (a == b));
    010     System.out.println("a != b liefert " + (a != b));
    011   }
    012 }
| Listing0506.java

Listing 5.6: Vergleichen von Referenzen

Werden sie zur Laufzeit angelegt (wie in diesem Beispiel), liefert das Programm das erwartete Ergebnis, denn `a` und `b` sind Referenzen auf unterschiedliche Objekte, also Zeiger auf unterschiedliche Instanzen derselben Klasse.

    a == b liefert false
    a != b liefert true

|  |  |  | Dies ist das erwartete Verhalten für fast alle Objektreferenzen. Werden die Strings als Literale dagegen zur Compile-Zeit angelegt und damit vom Compiler als konstant erkannt, sind sie genau dann Instanzen derselben Klasse, wenn sie tatsächlich inhaltlich gleich sind. Dies liegt daran, daß String-Literale mit Hilfe der Methode `String.intern` angelegt werden, die einen Puffer von `String`-Objekten verwaltet, in dem jede Zeichenkette nur einmal vorkommt. Wird ein bereits existierender String noch einmal angelegt, so findet die Methode den Doppelgänger und liefert einen Zeiger darauf zurück. Dieses Verhalten ist so nur bei Strings zu finden, andere Objekte besitzen keine konstanten Werte und keine literalen Darstellungen. Die korrekte Methode, Strings auf inhaltliche Übereinstimmung zu testen, besteht darin, die Methode `equals` der Klasse `String` aufzurufen (siehe Listing 5.7). |  |
Warnung

    001 /* Listing0507.java */
    002
    003 public class Listing0507
    004 {
    005   public static void main(String[] args)
    006   {
    007     String a = new String("hallo");
    008     String b = new String("hallo");
    009     System.out.println("a.equals(b) liefert " + a.equals(b));
    010   }
    011 }
| Listing0507.java

Listing 5.7: Vergleichen von Strings mit equals

#### Der instanceof-Operator

Der `instanceof`-Operator kann verwendet werden, um herauszufinden, zu welcher Klasse ein bestimmtes Objekt gehört. Der Ausdruck `a instanceof b` liefert genau dann `true`, wenn `a` und `b` Referenztypen sind und `a` eine Instanz der Klasse `b` oder einer ihrer Unterklassen ist. Falls das Ergebnis des `instanceof`-Operators nicht bereits zur Compile-Zeit ermittelt werden kann, generiert der Java-Compiler Code, um den entsprechenden Check zur Laufzeit durchführen zu können.

#### Der new-Operator

In Java werden Objekte und Arrays mit Hilfe des `new`-Operators erzeugt. Sowohl das Erzeugen eines Arrays als auch das Erzeugen eines Objekts sind Ausdrücke, deren Rückgabewert das gerade erzeugte Objekt bzw. Array ist.

#### Member-Zugriff

Der Zugriff auf Klassen- oder Instanzvariablen wird mit Hilfe des Punkt-Operators ausgeführt und hat die Form `a.b`. Dabei ist `a` der Name einer Klasse bzw. der Instanz einer Klasse, und `b` ist der Name einer Klassen- oder Instanzvariable. Der Typ des Ausdrucks entspricht dem Typ der Variable, und zurückgegeben wird der Inhalt dieser Variable.

#### Methodenaufruf

In Java gibt es keine Funktionen, sondern nur Methoden. Der Unterschied zwischen beiden besteht darin, daß Methoden immer an eine Klasse oder die Instanz einer Klasse gebunden sind und nur in diesem Kontext aufgerufen werden können. Die Syntax des Methodenaufrufs gleicht der anderer Programmiersprachen und erfolgt in der (etwas vereinfachten) Form `f()` bzw. `f(parameterliste)`. Der Typ des Ausdrucks entspricht dem vereinbarten Rückgabetyp der Methode. Der Wert des Ausdrucks ist der von der Methode mit Hilfe der `return`-Anweisung zurückgegebene Wert.

Methoden können selbstverständlich Nebeneffekte haben und werden in vielen Fällen ausschließlich zu diesem Zweck geschrieben. Ist dies der Fall, so sollte eine Methode als `void` deklariert werden und damit anzeigen, daß sie keinen Rückgabewert produziert. Die einzig sinnvolle Verwendung einer solchen Methode besteht darin, sie innerhalb einer Ausdrucksanweisung (siehe Kapitel 6) aufzurufen.

|  | Da die Realisierung der Methodenaufrufe in Java recht kompliziert ist (die Sprachspezifikation widmet diesem Thema mehr als 10 Seiten), werden wir in Kapitel 7 noch einmal ausführlich darauf eingehen. |  |
Hinweis

#### Zugriff auf Array-Elemente

Wie in anderen Programmiersprachen erfolgt auch in Java der Zugriff auf Array-Elemente mit Hilfe eckiger Klammern in der Form `a[b]` (bzw. `a[b][c]`, `a[b][c][d]` usw. bei mehrdimensionalen Arrays). Dabei ist `a` der Name eines Arrays oder ein Ausdruck, der zu einem Array ausgewertet wird, und `b` ein Ausdruck, der zu einem `int` evaluiert werden kann. Der Typ des Ausdrucks entspricht dem Basistyp des Arrays, zurückgegeben wird der Inhalt des Array-Elements, das sich an Position `b` befindet. Wie in C und C++ beginnt die Zählung mit dem ersten Element bei Position 0.

### 5.7.3 Welche Operatoren es nicht gibt

|  | Da es in Java keine expliziten Pointer gibt, fehlen auch die aus C bekannten Operatoren `*` zur Dereferenzierung eines Zeigers und `&` zur Bestimmung der Adresse einer Variablen. Des weiteren fehlt ein `sizeof`-Operator, denn da alle Typen eine genau spezifizierte Länge haben, ist dieser überflüssig. Der Kommaoperator von C ist ebenfalls nicht vorhanden, er taucht aber als syntaktischer Bestandteil der `for`-Schleife wieder auf und erlaubt es, im Initialisierungsteil der Schleife mehr als eine Zuweisung vorzunehmen. |  |
Hinweis

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