Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 5. Auflage
 <<    <     >    >>   API  Kapitel 6 - Anweisungen

6.2 Verzweigungen



Verzweigungen in Java dienen wie in allen Programmiersprachen dazu, bestimmte Programmteile nur beim Eintreten vorgegebener Bedingungen, die erst zur Laufzeit bekannt werden, auszuführen. An Verzweigungen bietet Java die if- und if-else-Anweisung sowie die switch-Anweisung.

6.2.1 Die if-Anweisung

Syntax

if (ausdruck)
  anweisung;

oder

if (ausdruck)
  anweisung1;
else
  anweisung2;

Bedeutung

Die if-Anweisung wertet zunächst den Ausdruck ausdruck aus. Danach führt sie die Anweisung anweisung genau dann aus, wenn das Ergebnis des Ausdrucks true ist. Ist ausdruck hingegen false, so wird die Anweisung nicht ausgeführt, sondern mit der ersten Anweisung nach der if-Anweisung fortgefahren.

Mit der if-else-Anweisung gibt es eine weitere Verzweigung in Java. Falls ausdruck wahr ist, wird anweisung1 ausgeführt, andernfalls anweisung2. Eine der beiden Anweisungen wird also in jedem Fall ausgeführt.

Anstelle einer einzelnen Anweisung kann jeweils auch eine Folge von Anweisungen angegeben werden, wenn sie innerhalb eines Blocks steht. Dieser wird als Einheit betrachtet und komplett ausgeführt, wenn die entsprechende Bedingung zutrifft.

Zu beachten ist, dass der Testausdruck in der Schleife vom Typ boolean sein muss. Anders als in C ist es in Java nicht erlaubt, einen numerischen Ausdruck an seiner Stelle zu verwenden.

 Hinweis 

Dangling else

Eine der Mehrdeutigkeiten, die in fast allen blockstrukturierten Programmiersprachen auftauchen können, wurde auch von den Java-Entwicklern nicht beseitigt. Als Beispiel wollen wir uns das folgende Codefragment ansehen, das leider nicht so ausgeführt wird, wie es die Einrückung erwarten läßt:

 Warnung 

001 if (a)
002   if (b)
003     s1;
004 else
005   s2;
Listing 6.2: Dangling else

Der else-Zweig gehört zu der innersten Verzweigung if (b)..., und die korrekte Einrückung würde lauten:

001 if (a)
002   if (b)
003     s1;
004   else
005     s2;
Listing 6.3: Dangling else, ausgeschaltet

Dieses Problem ist in der Literatur unter dem Namen dangling else bekannt und kann nur auftauchen, wenn eine if- und eine if-else-Verzweigung ineinander geschachtelt werden und beide Anweisungen nicht durch Blockklammern begrenzt wurden. Um die Mehrdeutigkeit zu beseitigen, wird in Java wie auch in C oder C++ ein »freies« else immer an das am weitesten innen liegende if angehängt.

Bedingtes Kompilieren

Eine weitere Besonderheit der Verzweigungen in Java rührt daher, dass die Sprache keinen Präprozessor besitzt und deshalb kein #ifdef kennt. Um eine eingeschränkte Form der bedingten Kompilierung zu verwirklichen, wird in Java das folgende Programmfragment in der Weise kompiliert, dass die Anweisung anweisung nicht mitübersetzt wird, da der Testausdruck konstant false ist:

001 if (false)
002   anweisung;
Listing 6.4: Bedingtes Kompilieren

 Tipp 

Allerdings sollte man hinzufügen, dass ein solches Verhalten in der Sprachspezifikation zwar dringend empfohlen wird, für die Compiler-Bauer aber nicht zwangsläufig verpflichtend ist.

Das hier beschriebene Verhalten eines Java-Compilers steht im Widerspruch zu einer anderen Forderung, nämlich der, nur erreichbare Anweisungen zu akzeptieren. Gemäß Sprachspezifikation soll der Compiler alle Anweisungen, die nicht erreichbar sind, ablehnen, also einen Fehler melden.

Nicht erreichbar im technischen Sinne sind dabei Anweisungen in Schleifen, deren Testausdruck zur Compile-Zeit false ist, und Anweisungen, die hinter einer break-, continue-, throw- oder return-Anweisung liegen, die unbedingt angesprungen wird. Die einzige Ausnahme von dieser Regel ist die im vorigen Absatz erwähnte Variante der konstant unwahren Verzweigung, die zur bedingten Kompilierung verwendet werden kann.

6.2.2 Die switch-Anweisung

Syntax

switch (ausdruck)
{
  case constant:
    anweisung;
  ...
  default:
}

Bedeutung

Die switch-Anweisung ist eine Mehrfachverzweigung. Zunächst wird der Ausdruck ausdruck, der vom Typ byte, short, char oder int sein muss, ausgewertet. In Abhängigkeit vom Ergebnis wird dann die Sprungmarke angesprungen, deren Konstante mit dem Ergebnis des Ausdrucks übereinstimmt. Die Konstante und der Ausdruck müssen dabei zuweisungskompatibel sein.

Das optionale default-Label wird dann angesprungen, wenn keine passende Sprungmarke gefunden wird. Ist kein default-Label vorhanden und wird auch keine passende Sprungmarke gefunden, so wird keine der Anweisungen innerhalb der switch-Anweisung ausgeführt. Jede Konstante eines case-Labels darf nur einmal auftauchen. Das default-Label darf maximal einmal verwendet werden.

Nachdem ein case- oder default-Label angesprungen wurde, werden alle dahinterstehenden Anweisungen ausgeführt. Im Gegensatz zu Sprachen wie PASCAL erfolgt auch dann keine Unterbrechung, wenn das nächste Label erreicht wird. Wenn dies erwünscht ist, muss der Kontrollfluss wie in C und C++ mit Hilfe einer break-Anweisung unterbrochen werden. Jedes break innerhalb einer switch-Anweisung führt dazu, dass zum Ende der switch-Anweisung verzweigt wird.

 Warnung 

Wie aus den bisherigen Ausführungen deutlich wurde, ist die Semantik der switch-Anweisung in Java der in C und C++ sehr ähnlich. Ein wichtiger Unterschied besteht darin, dass in Java alle Anweisungen, die unmittelbar innerhalb des switch liegen, case- oder default-Labels sein müssen. Der Trick, in switch-Anweisungen Schleifen zu packen, die sich über mehrere Labels erstrecken, funktioniert in Java nicht. Die Sprachspezifikation erläutert dies am Beispiel von Duff's Device, das so in Java nicht kompilierbar ist:

001 int q = (n+7)/8;
002 switch (n%8) {
003 case 0: do { foo();
004 case 1:      foo();
005 case 2:      foo();
006 case 3:      foo();
007 case 4:      foo();
008 case 5:      foo();
009 case 6:      foo();
010 case 7:      foo();
011         } while (--q >= 0);
012 }
Listing 6.5: Duff's Device

Glücklicherweise ist derartiger Code mehr zur Verwirrung ahnungsloser Programmierer gedacht als zur ernsthaften Anwendung und kommt in der Praxis normalerweise kaum vor.


 Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 5. Auflage, Addison Wesley, Version 5.0.2
 <<    <     >    >>   API  © 1998, 2007 Guido Krüger & Thomas Stark, http://www.javabuch.de