Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Mathematisches
6 Eigene Klassen schreiben
7 Angewandte Objektorientierung
8 Exceptions
9 Generics, innere Klassen
10 Die Klassenbibliothek
11 Threads und nebenläufige Programmierung
12 Datenstrukturen und Algorithmen
13 Raum und Zeit
14 Dateien und Datenströme
15 Die eXtensible Markup Language (XML)
16 Grafische Oberflächen mit Swing
17 Grafikprogrammierung
18 Netzwerkprogrammierung
19 Verteilte Programmierung mit RMI und Web–Services
20 JavaServer Pages und Servlets
21 Applets
22 Midlets und die Java ME
23 Datenbankmanagement mit JDBC
24 Reflection und Annotationen
25 Logging und Monitoring
26 Sicherheitskonzepte
27 Java Native Interface (JNI)
28 Dienstprogramme für die Java-Umgebung
Stichwort

Download:
- ZIP, ca. 14,1 MB
Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel (8. Auflage) von Christian Ullenboom
Programmieren mit der Java Standard Edition Version 6
Buch: Java ist auch eine Insel (8. Auflage)

Java ist auch eine Insel (8. Aufl.)
8., aktual. Auflage, geb., mit DVD
1.475 S., 49,90 Euro
Galileo Computing
ISBN 978-3-8362-1371-4
Pfeil 2 Sprachbeschreibung
Pfeil 2.1 Elemente der Programmiersprache Java
Pfeil 2.1.1 Token
Pfeil 2.1.2 Textkodierung durch Unicode-Zeichen
Pfeil 2.1.3 Literale
Pfeil 2.1.4 Bezeichner
Pfeil 2.1.5 Reservierte Schlüsselwörter
Pfeil 2.1.6 Kommentare
Pfeil 2.1.7 Die API-Dokumentation
Pfeil 2.2 Anweisungen formen Programme
Pfeil 2.2.1 Anweisungen
Pfeil 2.2.2 Eine Klasse bildet den Rahmen
Pfeil 2.2.3 Die Reise beginnt am main()
Pfeil 2.2.4 Funktionsaufrufe als Anweisungen
Pfeil 2.2.5 print(), println() und printf() für Bildschirmausgaben
Pfeil 2.2.6 Ausdrucksanweisung
Pfeil 2.2.7 Erste Idee der Objektorientierung
Pfeil 2.2.8 Modifizierer
Pfeil 2.2.9 Anweisungen und Blöcke
Pfeil 2.3 Datentypen, Typisierung, Variablen und Zuweisungen
Pfeil 2.3.1 Primitive Datentypen im Überblick
Pfeil 2.3.2 Variablendeklarationen
Pfeil 2.3.3 Zuweisungsoperator
Pfeil 2.3.4 Variablendeklaration mit Wertinitialisierung
Pfeil 2.3.5 Wahrheitswerte
Pfeil 2.3.6 Ganzzahlige Datentypen
Pfeil 2.3.7 Die Fließkommazahlen float und double
Pfeil 2.3.8 Alphanumerische Zeichen
Pfeil 2.3.9 Gute Namen, schlechte Namen
Pfeil 2.4 Blöcke, Initialisierung und Sichtbarkeit
Pfeil 2.4.1 Blöcke und Anweisungen
Pfeil 2.4.2 Initialisierung von lokalen Variablen
Pfeil 2.4.3 Sichtbarkeit und Gültigkeitsbereich
Pfeil 2.5 Ausdrücke, Operanden und Operatoren
Pfeil 2.5.1 Arithmetische Operatoren
Pfeil 2.5.2 Unäres Minus und Plus
Pfeil 2.5.3 Zuweisung mit Operation
Pfeil 2.5.4 Präfix- oder Postfix-Inkrement und -Dekrement
Pfeil 2.5.5 Die relationalen Operatoren und die Gleichheitsoperatoren
Pfeil 2.5.6 Logische Operatoren Und, Oder, Xor, Nicht
Pfeil 2.5.7 Rang der Operatoren in der Auswertungsreihenfolge
Pfeil 2.5.8 Die Typanpassung (das Casting)
Pfeil 2.5.9 Überladenes Plus für Strings
Pfeil 2.6 Bedingte Anweisungen oder Fallunterscheidungen
Pfeil 2.6.1 Die if-Anweisung
Pfeil 2.6.2 Die Alternative mit einer if/else-Anweisung wählen
Pfeil 2.6.3 Die switch-Anweisung bietet die Alternative
Pfeil 2.7 Schleifen
Pfeil 2.7.1 Die while-Schleife
Pfeil 2.7.2 Die do-while-Schleife
Pfeil 2.7.3 Die for-Schleife
Pfeil 2.7.4 Schleifenbedingungen und Vergleiche mit ==
Pfeil 2.7.5 Ausbruch planen mit break und Wiedereinstieg mit continue
Pfeil 2.7.6 break und continue mit Sprungmarken
Pfeil 2.8 Methoden einer Klasse
Pfeil 2.8.1 Bestandteil einer Funktion
Pfeil 2.8.2 Signatur-Beschreibung in der Java-API
Pfeil 2.8.3 Aufruf einer Methode
Pfeil 2.8.4 Methoden ohne Parameter deklarieren
Pfeil 2.8.5 Statische Methoden (Klassenmethoden)
Pfeil 2.8.6 Parameter, Argument und Wertübergabe
Pfeil 2.8.7 Methoden vorzeitig mit return beenden
Pfeil 2.8.8 Nicht erreichbarer Quellcode bei Funktionen
Pfeil 2.8.9 Rückgabewerte
Pfeil 2.8.10 Methoden überladen
Pfeil 2.8.11 Vorgegebener Wert für nicht aufgeführte Argumente
Pfeil 2.8.12 Finale lokale Variablen
Pfeil 2.8.13 Rekursive Methoden
Pfeil 2.9 Weitere Operatoren
Pfeil 2.9.1 Bits und Bytes
Pfeil 2.9.2 Operationen auf Bit-Ebene
Pfeil 2.9.3 Die Verschiebeoperatoren
Pfeil 2.9.4 Ein Bit setzen, löschen, umdrehen und testen
Pfeil 2.9.5 Bit-Funktionen der Integer- und Long-Klasse
Pfeil 2.9.6 Der Bedingungsoperator
Pfeil 2.9.7 Operator vermisst
Pfeil 2.10 Einfache Benutzereingaben
Pfeil 2.11 Zum Weiterlesen


Galileo Computing - Zum Seitenanfang

2.9 Weitere Operatoren Zur nächsten ÜberschriftZur vorigen Überschrift

Die bisher angesprochenen arithmetischen und relationalen Operatoren finden sich in nahezu jedem Programm. Seltener sind schon Operatoren, die auf Bit-Ebene operieren. Sie sollen im Folgenden vorgestellt werden.


Galileo Computing - Zum Seitenanfang

2.9.1 Bits und Bytes Zur nächsten ÜberschriftZur vorigen Überschrift

Ein Bit ist ein Informationsträger für die Aussage wahr oder falsch. Durch das Zusammensetzen von einzelnen Bits entstehen größere Folgen wie das Byte, das aus acht Bit besteht. Da jedes Bit anders belegt sein kann, bildet es in der Summe unterschiedliche Werte. Werden acht Bit zugrunde gelegt, so lassen sich durch unterschiedliche Belegungen 256 unterschiedliche Zahlen bilden. Ist kein Bit des Bytes gesetzt, so ist die Zahl 0. Jede Stelle im Byte bekommt dabei eine Wertigkeit zugeordnet. Die Wertebelegung für die Zahl 19 berechnet sich aus 16 + 2 + 1, da sie aus einer Anzahl von Summanden der Form 2^n zusammengesetzt ist: 19dez = 16 + 2 + 1 = 1*2^4 + 0*2^3 + 0*2^2 + 1*2^1 + 1*2^0 =10011bin.


Bit 7 6 5 4 3 2 1 0

Wertigkeit

27 =128

26 =64

25 =32

24 =16

23 =8

22 =4

21 =2

20 =1

Belegung für 19

0

0

0

1

0

0

1

1



Galileo Computing - Zum Seitenanfang

2.9.2 Operationen auf Bit-Ebene Zur nächsten ÜberschriftZur vorigen Überschrift

Mit Bit-Operatoren lassen sich Binäroperationen auf Operanden durchführen, um beispielsweise ein Bit eines Bytes zu setzen. Zu den Bit-Operationen zählen Verknüpfungen, Schiebeoperationen und das Komplement. Durch die bitweisen Operatoren können einzelne Bits abgefragt und manipuliert werden. Als Verknüpfungen bietet Java die folgenden Bit-Operatoren an:


Tabelle 2.9 Bit-Operatoren in Java

Operator Bezeichnung Funktion

~

Komplement

Invertiert jedes Bit.

|

bitweises Oder

Bei a | b wird jedes Bit von a und b einzeln Oder-verknüpft.

&

bitweises Und

Bei a & b wird jedes Bit von a und b einzeln Und-verknüpft.

^

bitweises exklusives Oder (Xor)

Bei a ^ b wird jedes Bit von a und b einzeln Xor-verknüpft; es ist kein a hoch b.


Betrachten wir allgemein die binäre Verknüpfung a # b. Bei der binären bitweisen Und-Verknüpfung mit & gilt für jedes Bit: Ist im Operand a irgendein Bit gesetzt und an gleicher Stelle auch im Operand b, so ist auch das Bit an der Stelle im Ergebnis gesetzt. Bei der Oder-Verknüpfung mit | muss nur einer der Operanden gesetzt sein, damit das Bit im Ergebnis gesetzt ist. Bei einem exklusiven Oder (Xor) ist das Ergebnis 1, wenn nur genau einer der Operanden 1 ist. Sind beide gemeinsam 0 oder 1, ist das Ergebnis 0. Dies entspricht einer binären Addition oder Subtraktion. Fassen wir das Ergebnis noch einmal in einer Tabelle zusammen:


Tabelle 2.10 Bit-Operatoren Komplement, Und, Oder, Xor in einer Wahrheitstafel

Bit 1 Bit 2 ~Bit 1 Bit 1 & Bit 2 Bit 1 | Bit 2 Bit 1 ^ Bit 2

0

0

1

0

0

0

0

1

1

0

1

1

1

0

0

0

1

1

1

1

0

1

1

0


Nehmen wie zum Beispiel zwei Ganzahlen.


binär dezimal

Zahl 1

010011

16 + 2 + 1 = 19

Zahl 2

100010

32 + 2 = 34

Zahl 1 & Zahl 2

000010

19 & 34 = 2

Zahl l | Zahl 2

110011

19 | 34 = 51

Zahl 1 ^ Zahl 2

110001

19 ^ 34 = 49


Vorzeichenlose Zahlen in ein Integer und Char konvertieren

Liegt ein Byte als Datentyp vor, so kann es zwar automatisch zu einem int angepasst werden, aber die automatische Typkonvertierung erfüllt nicht immer den gewünschten Zweck.

byte b1 =        100; 
byte b2 = (byte) 200; 
System.out.println( b1 );    // dezimal 100, binär: 1100100 
System.out.println( b2 );    // dezimal –56, binär: 1001000

Beim zweiten Byte ist eine Typanpassung nötig, da 200 den Zahlenbereich eines Bytes von –128 bis 127 überschreitet. Dennoch kann ein Byte das gegebene Bitmuster annehmen und repräsentiert dann die negative Zahl 56. Wird diese ausgegeben, findet bei println(int) eine automatische Typanpassung auf ein int statt, und die im byte gespeicherte negative Zahl wird zur negativen int-Zahl konvertiert. Das bedeutet, dass das Vorzeichen übernommen wird.

In einigen Fällen ist es wünschenswert, ein byte vorzeichenlos zu behandeln. Bei der Ausgabe soll dann ein Datenwert zwischen 0 und 255 herauskommen. Um das zu erreichen, schneiden wir mit der Und-Verknüpfung – alle anderen Bits ausgenommen – die unteren acht heraus. Das reicht schon. Die Lösung zeigt die Funktion byteToInt():

static int byteToInt( byte b ) 
{ 
  return b & 0xff; 
}

Eine explizite Typanpassung mit (int) b ist nicht nötig, da die implizite Anpassung das Byte b in einer arithmetischen Operation automatisch auf ein int konvertiert.

Mit einer ähnlichen Arbeitsweise können wir auch die Frage lösen, wie sich ein Byte, dessen Integerwert im Minusbereich liegt, in ein char konvertieren lässt. Der erste Ansatz über eine Typumwandlung (char) byte ist falsch, und auf der Ausgabe dürfte nur ein rechteckiges Kästchen oder ein Fragezeichen erscheinen:

byte b = (byte) 'ß'; 
System.out.println( (char) b );    // Ausgabe ist  ?

Das Dilemma ist wieder die fehlerhafte Vorzeichenanpassung. Bei der Benutzung des Bytes wird es zuerst in ein int konvertiert. Das »ß« wird dann zu –33. Im nächsten Schritt wird diese –33 dann zu einem char umgesetzt. Das ergibt 65.503, was einen Unicode-Bereich trifft, der zurzeit kein Zeichen definiert. Es wird wohl auch noch etwas dauern, bis die ersten Außerirdischen uns neue Zeichensätze schenken. Gelöst wird der Fall wie oben, indem von b nur die unteren acht Bits betrachtet werden. Das geschieht wieder durch ein Ausblenden über den Und-Operator. Damit ergibt sich korrekt:

char c = (char) (b & 0x00ff);

Variablen mit Xor vertauschen

Eine besonders trickreiche Idee für das Vertauschen von Variableninhalten arbeitet mit der Xor-Funktion und benötigt keine temporäre Zwischenvariable. Die Zeilen zum Vertauschen von x und y lauten wie folgt:

int x = 12, 
    y = 49; 
x ^= y; // x = x ^ y = 001100bin ^ 110001bin = 111101bin 
y ^= x; // y = y ^ x = 110001bin ^ 111101bin = 001100bin 
x ^= y; // x = x ^ y = 111101bin ^ 001100bin = 110001bin 
System.out.println( x + " " + y );  // Ausgabe ist: 49 12

Der Trick funktioniert, da wir mit Xor etwas »hinein- und herausrechnen« können. Zuerst rechnet die erste Zeile das y in das x. Wenn wir anschließend die Zuweisung an das y machen, dann ist das der letzte schreibende Zugriff auf y, also muss hier schon das vertauschte Ergebnis stehen. Das stimmt auch, denn expandieren wir die zweite Zeile, steht dort: »y ^ x wird zugewiesen an y«, und dies ist y ^ (x ^ y). Der letzte Ausdruck verkürzt sich zu y = x, da aus der Definition der Xor-Funktion für einen Wert a hervorgeht: a ^ a = 0. Die Zuweisung hätten wir zwar gleich so schreiben können, aber dann wäre der Wert von y verloren gegangen. Der steckt aber noch in x aus der ersten Zuweisung. Betrachten wir daher die letzte Zeile x ^ y: y hat den Startwert von x, doch in x steckt ein Xor-y. Daher ergibt x ^ y den Wert x ^ x ^ y, und der verkürzt sich zu y. Demnach haben wir den Inhalt der Variablen vertauscht. Im Übrigen können wir für die drei Xor-Zeilen alternativ schreiben:

y ^= x ^= y;   // Auswertung automatisch y ^= (x ^= y) 
x ^= y;

Da liegt es doch nahe, die Ausdrücke weiter abzukürzen zu x ^= y ^= x ^= y. Doch leider ist das falsch (es kommt für x immer null heraus). Den motivierten Lesern bleibt dies als Denksportaufgabe überlassen.


Galileo Computing - Zum Seitenanfang

2.9.3 Die Verschiebeoperatoren Zur nächsten ÜberschriftZur vorigen Überschrift

Unter Java gibt es drei Verschiebeoperatoren (engl. shift-operator), die die Bits eines Wertes um eine gewisse Anzahl Positionen verschieben können:

  • n << s. Linksverschieben der Bits von n um s Positionen
  • n >> s. Arithmetisches Rechtsverschieben um s Positionen mit Vorzeichen
  • n >>> s. Logisches Rechtsverschieben um s Positionen ohne Vorzeichen

Die binären Verschiebeoperatoren bewegen alle Bits eines Datenworts (das Bitmuster) nach rechts oder links. Bei der Verschiebung steht nach dem binären Operator, also im rechten Operanden, die Anzahl Positionen, um die verschoben wird. Obwohl es nur zwei Richtungen gibt, muss noch der Fall betrachtet werden, ob das Vorzeichen bei der Rechtsverschiebung beachtet wird oder nicht. Das wird dann arithmetisches Verschieben (Vorzeichen verschiebt sich mit) oder logisches Verschieben (Vorzeichen wird mit 0 aufgefüllt) genannt.

n << s

Die Bits des Operanden n werden unter Berücksichtigung des Vorzeichens s-mal nach links geschoben (mit 2 multipliziert). Der rechts frei werdende Bit-Platz wird immer mit 0 aufgefüllt. Das Vorzeichen ändert sich jedoch, sobald eine 1 von der Position MSB – 1 nach MSB geschoben wird. (MSB steht hier für Most Significant Bit, also das Bit mit der höchsten Wertigkeit in der binären Darstellung.)


Hinweis Zwar ist der Datentyp des rechten Operators erst einmal ein int beziehungsweise long mit vollem Wertebereich, doch als Verschiebepositionen sind bei int nur Werte bis 31 sinnvoll und für ein long Werte bis 63 Bit, da nur die letzten 5 bzw. 6 Bit berücksichtigt werden. Sonst wird immer um den Wert verschoben, der sich durch das Teilen durch 32 bzw. 64 als Rest ergibt, sodass x << 32 und x << 0 auch gleich ist.

System.out.println( 1 << 30 );  // 1073741824 
System.out.println( 1 << 31 );  // –2147483648 
System.out.println( 1 << 32 );  // 1

n >> s (arithmetisches Rechtsschieben)

Beim Verschieben nach rechts wird je nachdem, ob das Vorzeichen-Bit gesetzt ist oder nicht, eine 1 oder eine 0 von links eingeschoben; das linke Vorzeichen-Bit bleibt unberührt.


Beispiel Ein herausgeschobenes Bit ist für immer verloren!

System.out.println( 65535 >> 8 );  // 255 
System.out.println(   255 << 8);   // 65280

Es ist 65.535 = 0xFFFF, und nach der Rechtsverschiebung 65.535 >> 8 ergibt sich 0x00FF = 255. Schieben wir nun wieder nach links, also 0x00FF << 8, dann ist das Ergebnis 0xFF00 = 65.280.


Bei den Ganzzahldatentypen folgt unter Berücksichtigung des immer vorhandenen Vorzeichens bei normalen Rechtsverschiebungen eine vorzeichenrichtige Ganzzahldivision durch 2.

n >>> s (logisches Rechtsschieben)

Der Operator >>> berücksichtigt das Vorzeichen der Variablen nicht, sodass eine vorzeichenlose Rechtsverschiebung ausgeführt wird. So werden auf der linken Seite (MSB) nur Nullen eingeschoben; das Vorzeichen wird mitgeschoben.


Beispiel Mit den Verschiebe-Operatoren lassen sich die einzelnen Bytes eines größeren Datentyps, etwa eines 4 Byte großen int, einfach extrahieren:

byte b1 = (byte)(v >>> 24), 
     b2 = (byte)(v >>> 16), 
     b3 = (byte)(v >>>  8), 
     b4 = (byte)(v       );

Bei einer positiven Zahl hat dies keinerlei Auswirkungen, und das Verhalten ist wie beim >>-Operator.


Beispiel Die Ausgabe ist für den negativen Operanden besonders spannend:

System.out.println(  64 >>> 1 );  // 32 
System.out.println( –64 >>> 1 );  // 2147483616

Ein <<<-Operator ergibt keinen Sinn, da die Linksverschiebung ohnehin nur Nullen rechts einfügt.


Galileo Computing - Zum Seitenanfang

2.9.4 Ein Bit setzen, löschen, umdrehen und testen Zur nächsten ÜberschriftZur vorigen Überschrift

Die Bit-Operatoren lassen sich zusammen mit den Verschiebeoperatoren gut dazu verwenden, ein Bit zu setzen respektive herauszufinden, ob ein Bit gesetzt ist. Betrachten wir folgende Funktionen, die ein bestimmtes Bit setzen, abfragen, invertieren und löschen:

int setBit( int n, int pos ) 
{ 
  return n | (1 << pos); 
} 
 
int clearBit( int n, int pos ) 
{ 
  return n & ~(1 << pos); 
} 
 
int flipBit( int n, int pos ) 
{ 
  return n ^ (1 << pos); 
} 
boolean testBit( int n, int pos ) 
{ 
  int mask = 1 << pos; 
 
  return (n & mask) == mask; 
  // alternativ: return (n & 1<<pos) != 0; 
}

Galileo Computing - Zum Seitenanfang

2.9.5 Bit-Funktionen der Integer- und Long-Klasse Zur nächsten ÜberschriftZur vorigen Überschrift

Die Klassen Integer und Long bieten eine Reihe von statischen Funktionen zur Bit-Manipulation und zur Abfrage diverser Bit-Zustände von ganzen Zahlen. Die Schreibweise int|long kennzeichnet durch int die Funktionen der Klasse Integer und durch long die Funktionen der Klasse Long.


final class java.lang.Integer | java.lang.Long 
extends Number 
implements Comparable<Integer> | implements Comparable<Long>

  • static int|long bitCount( int|long i )
    Liefert die Anzahl gesetzter Bits.
  • static int|long reverse( int|long i )
    Dreht die Reihenfolge der Bits um.
  • static int|long reverseBytes( int|long i )
    Setzt die vier Bytes eines int in die umgekehrte Reihenfolge.
  • static int|long rotateLeft( int|long i, int distance )
  • static int|long rotateRight( int|long i, int distance )
    Rotiert die Bits um distance Positionen nach links oder nach rechts.
  • static int|long highestOneBit( int|long i )
  • static int|long lowestOneBit( int|long i )
    Liefert einen Wert, wobei nur das höchste (links stehende) bzw. niedrigste (rechts stehende) Bit gesetzt ist. Es ist also nur höchstens ein Bit gesetzt; bei Argument 0 ist natürlich kein Bit gesetzt und das Ergebnis ebenfalls null.
  • static int|long numberOfLeadingZeros( int|long i )
  • static int|long numberOfTrailingZeros( int|long i )
    Liefert die Anzahl der Null-Bits vor dem höchsten bzw. nach dem niedrigsten gesetzten Bit.

Beispiel Anwendung der Bit-Funktionen der Klasse Long.

Listing 2.22 BitTwiddling.java, main()

out.println( Long.highestOneBit( 8 – 1 ) );                 // 4 
out.println( Long.lowestOneBit( 2 + 4 ) );                  // 2 
out.println( Long.numberOfLeadingZeros( Long.MAX_VALUE ) ); // 1 
out.println( Long.numberOfLeadingZeros( -Long.MAX_VALUE ) );// 0 
out.println( Long.numberOfTrailingZeros( 16 ) );            // 4 
out.println( Long.numberOfTrailingZeros( 3 ) );             // 0 
out.println( Long.bitCount( 8 + 4 +1 ) );                   // 3 
out.println( Long.rotateLeft( 12, 1 ) );                    // 24 
out.println( Long.rotateRight( 12, 1 ) );                   // 6 
out.println( Long.reverse( Long.MAX_VALUE ) );              // –2
out.println( Long.reverse( 0x0F00000000000000L ) );         // 240 
out.println( Long.reverseBytes( 0x0F00000000000000L ) );    // 15


Galileo Computing - Zum Seitenanfang

2.9.6 Der Bedingungsoperator Zur nächsten ÜberschriftZur vorigen Überschrift

In Java gibt es ebenso wie in C(++) einen Operator, der drei Operanden benutzt. Dies ist der Bedingungsoperator, der auch Konditionaloperator, ternärer Operator beziehungsweise trinärer Operator genannt wird. Er erlaubt es, den Wert eines Ausdrucks von einer Bedingung abhängig zu machen, ohne dass dazu eine if-Anweisung verwendet werden muss. Die Operanden sind durch ? beziehungsweise : voneinander getrennt.


Beispiel Die Bestimmung des Maximums ist eine schöne Anwendung des trinären Operators:

max = ( a > b ) ? a : b;

Der Wert der Variablen wird jetzt in Abhängigkeit von der Bedingung gesetzt. Der erste Ausdruck muss vom Typ boolean sein. Ist die Bedingung erfüllt, dann erhält die Variable den Wert des ersten Ausdrucks, andernfalls wird der Wert des zweiten Ausdrucks zugewiesen. Der Bedingungsoperator kann eingesetzt werden, wenn der zweite und dritte Operand ein numerischer Typ, boolescher Typ oder Referenztyp ist. Der Aufruf von Methoden, die demnach void zurückgeben, ist nicht gestattet.

Mit dem Rückgabewert können wir alles Mögliche machen, etwa ihn direkt ausgeben.

System.out.println( ( a > b ) ? a : b );

Das wäre mit if/else nur mit temporären Variablen möglich.

Beispiele

Der Bedingungsoperator findet sich häufig in kleinen Funktionen.

  • Das Maximum oder Minimum zweier Zahlen liefern die Ausdrücke a > b ? a : b beziehungsweise a < b ? a : b.
  • Den Absolutwert einer Zahl liefert x >= 0 ? x : -x.
  • Ein Ausdruck soll eine Zahl n, die zwischen 0 und 15 liegt, in eine Hexadezimalzahl konvertieren: (char)((n < 10) ? ('0' + n) : ('a' – 10 + n )).

Geschachtelte Anwendung vom Bedingungsoperator

Die Anwendung des trinären Operators führt schnell zu schlecht lesbaren Programmen, und er sollte daher vorsichtig eingesetzt werden. In C(++) führt die unbeabsichtigte Mehrfachauswertung in Makros zu schwer auffindbaren Fehlern. Gut, dass uns das in Java nicht passieren kann. Durch ausreichende Klammerung muss sichergestellt werden, dass die Ausdrücke auch in der beabsichtigten Reihenfolge ausgewertet werden. Im Gegensatz zu den meisten Operatoren ist der Bedingungsoperator rechtsassoziativ. (Die Zuweisung ist ebenfalls rechtsassoziativ.)

Der Ausdruck

b1 ? a1 : b2 ? a2 : a3

ist demnach gleichbedeutend mit:

b1 ? a1 : ( b2 ? a2 : a3 )

Beispiel Wollen wir eine Funktion schreiben, die für eine Zahl n abhängig vom Vorzeichen –1, 0 oder 1 liefert, lösen wir das Problem mit einem geschachtelten trinären Operator:

int sign( int n ) 
{ 
  return (n < 0) ? –1 : (n > 0) ? 1 : 0; 
}

Der Bedingungsoperator ist kein lvalue

Der trinäre Operator liefert als Ergebnis einen Ausdruck zurück, der auf der rechten Seite einer Zuweisung verwendet werden kann. Da er rechts vorkommt, nennt er sich auch rvalue. Er lässt sich nicht derart auf der linken Seite einer Zuweisung einsetzen, dass er eine Variable auswählt, der ein Wert zugewiesen wird. [In C(++) kann dies durch *((Bedingung) ? &a : &b) = Ausdruck; über Pointer gelöst werden.]


Beispiel Die folgende Anwendung des trinären Operators ist in Java nicht möglich:

((direction >= 0) ? up : down) = true;


Galileo Computing - Zum Seitenanfang

2.9.7 Operator vermisst topZur vorigen Überschrift

Da es in Java keine Pointer-Operationen gibt, existiert das unter C(++) bekannte Operatorzeichen zur Referenzierung (&) und Dereferenzierung (*) nicht. Ebenso ist ein sizeof unnötig, da das Laufzeitsystem und der Compiler immer die Größe von Klassen kennen beziehungsweise die primitiven Datentypen immer eine feste Länge haben. Eine abgeschwächte Version vom Kommaoperator ist in Java nur im Kopf von for-Schleifen erlaubt. Einige Programmiersprachen haben einen Potentoperator (etwa **), den es in Java ebenfalls nicht gibt. Skript-Sprachen wie Perl oder Python bieten nicht nur einfache Datentypen, sondern definieren zum Beispiel Listen oder Assoziativspeicher. Damit sind automatisch Operatoren assoziiert, etwa um die Datenstrukturen nach Werten zu fragen oder Elemente einzufügen. Zudem erlauben viele Skript-Sprachen das Prüfen von Zeichenketten gegenüber regulären Ausdrücken, etwa Perl mit den Operatoren =~ bzw. !~.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






<< zurück
  Zum Katalog
Zum Katalog: Java ist auch eine Insel





Java ist auch eine Insel
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Tipp
Zum Katalog: Coding for Fun





 Coding for Fun


 Buchempfehlungen
Zum Katalog: Objektorientierte Programmierung





 Objektorientierte
 Programmierung


Zum Katalog: Einstieg in Eclipse 3.4






 Einstieg in
 Eclipse 3.4


Zum Katalog: Java 6 lernen mit Eclipse






 Java 6 lernen
 mit Eclipse


Zum Katalog: NetBeans Platform 6






 NetBeans
 Platform 6


Zum Katalog: Java und XML






 Java und XML


Zum Katalog: Visual C# 2008






 Visual C# 2008


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Katalog: C++ von A bis Z






 C++ von A bis Z


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de