From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001
From: Sven Eisenhauer
+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.
+
+
+
+
+
+
+oder
+
+
+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.
+
+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:
+
+
+
+ Titel
+ Inhalt
+ Suchen
+ Index
+ DOC
+ Handbuch der Java-Programmierung, 5. Auflage
+
+ <<
+ <
+ >
+ >>
+ API
+ Kapitel 6 - Anweisungen
+
+
+
+
+
+6.2 Verzweigungen
+
+
+
+
+
+6.2.1 Die if-Anweisung
+
+
+
+
+Syntax
+
+
+
+
+
+
+
+
+
+if (ausdruck)
+ anweisung;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if (ausdruck)
+ anweisung1;
+else
+ anweisung2;
+
+
+Bedeutung
+
+
+
+
+
+
+
+
+
+
+
+![]()
+
+
+
+![]()
+
+
+
+
+
+ Hinweis
+
+
Dangling else
+
+
+
+
+
+
+
+
+![]()
+
+![]()
+
+
+
+![]()
+
+
+
+
+
+ Warnung
+
+
+
+
+Listing 6.2: Dangling else
+
+
+
+
+
+001 if (a)
+002 if (b)
+003 s1;
+004 else
+005 s2;
+
+
+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;+ + |
+
+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. + + + + +
+
![]() |
+![]() |
+
+
+ +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: + + + +
|
+
+
|
+![]() |
+
+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. + + + + +
+
+
+
+switch (ausdruck)
+{
+ case constant:
+ anweisung;
+ ...
+ default:
+}
+
+
+ |
+
+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. |
+
+
|
+![]() |
+
+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 }
+
+ |
+
+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.1 + |
| << + | < + | > + | >> + | API + | © 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de + |