Java-Kurs: Abfrage
Willemers Informatik-Ecke
Kontrollstrukturen Bedingungen (boolesche Ausdrücke)

Abfragen

Der Befehl if leitet eine Abfrage ein. In Klammern folgt eine Bedingung. Ist diese erfüllt, wird der nächste Befehl bzw. der nächste Block von Befehlen ausgeführt. Optional kann der Befehl else verwendet werden, um einen Befehl bzw. einen Block von Befehlen auszuführen, wenn die Bedingung nicht zutrifft.

Der Syntaxgraph für den if-Befehl sieht so aus:

Man könnte die Syntaxregel auch so schreiben:

if ( Bedingung ) Statement;
if ( Bedingung ) Statement1; else Statement2;

Ein typisches Beispiel ist die Abfrage vor einer Division, ob der Nenner eventuell 0 ist.

if (nenner==0)
    System.out.println(“Nenner ist gleich 0”);
else
    ergebnis = zaehler / nenner;
Statt einer einzelnen Anweisung kann auch ein Block von Anweisungen verwendet werden, indem die Anweisungen in geschweiften Klammern zusammengefasst werden.
if (nenner==0) {
    System.out.println(“Nenner ist gleich 0”);
} else {
    ergebnis = zaehler / nenner;
}

Vorsicht beim Setzen des Semikolons!

Weder hinter der Bedingungsklammer des ifs noch hinter dem else darf direkt ein Semikolon gesetzt werden.

if (nenner==0);   // Vorsicht! Hier darf kein Semikolon stehen!
    System.out.println(“Nenner ist gleich 0”);
else!            // Vorsicht! Hier darf kein Semikolon stehen!
    ergebnis = zaehler / nenner;
Sie können normalerweise Ihren Quelltext mit beliebigen Semikolen würzen, ohne dass ein Problem auftritt. Steht zwischen zwei Semikolen nichts, ist das eben eine durchaus zulässige leere Anweisung.

Im besonderen Falle der if-Abfrage würde das Semikolon hinter der Bedingung eine leere Anweisung definieren, die unter der Bedingung ausgeführt wird. Die zweite Zeile gehört dann nicht mehr dazu und wird auf jeden Fall ausgeführt. Der Compiler merkt nichts, aber die if-Abfrage wird nicht beachtet.

Das Gleiche gilt für das else. Steht direkt hinter dem else ein Semikolon, wird diese leere Anweisung zum else-Fall. Die nachfolgende Anweisung wird auf jeden Fall ausgeführt.

Verschachtelte Abfragen

UND-Verknüpfung

Man kann if-Abfragen ineinander verschachteln. Um die innerste Anweisung zu erreichen, müssen beide Bedingungen zutreffen. Aussagenlogisch entspricht dies einer UND-Bedingung.

Ein Beispiel ist die Abfrage, ob ein Wert innerhalb eines Intervalls liegt.

public class Intervall {
    public static void main(String[] args) {
        int a = 18;
        if (a > 15) {
            if (a < 25) {
                System.out.println(“ok!“);
            } else {
                // kühlen!
            }
        } else {
            // heizen!
        }
    }
}

dangeling else

Wenn es bei zwei if-Anweisungen nur ein else gibt, gehört dieses immer zum inneren if. Beispiel:

if (b1)
    if (b2)
        a1;
else
    a2;

Der else-Zweig mit a2 gehört trotz der anders scheinenden Einrückung zum if mit b2.

Das Problem des Dangeling Else kann nicht auftreten, wenn man geschweifte Klammern verwendet. Damit wird die Situation eindeutig. Da auch insgesamt die Übersichtlichkeit zunimmt, sollte man Abfragen immer mit geschweiften Klammern verwenden.

Kaskadierende Abfragen

Wenn Sie hinter dem else gleich wieder ein if setzen, können Sie eine Kaskade von mehreren Abfragen bauen, die auf verschiedene Werte einer Variable abfragt:
if (muenzwert == 200) {
    // 2 Euro-Münze
} else if (muenzwert == 100) {
    // 1 Euro-Münze
} else if (muenzwert == 50) {
    // 50 Cent-Münze
} else if (muenzwert == 20) {
    // 20 Cent-Münze
} else if (muenzwert == 10) {
    // 10 Cent-Münze
} else {
    // Kleinvieh
}

Fallunterscheidung

Eine Sonderform der Abfrage ist die Fallunterscheidung. Hier wird bei abzählbaren Variablentypen der Inhalt einer Variablen mit verschiedenen Konstanten verglichen.
switch (ausdruck)
{
   case constant1:
       anweisung1;
   case constant2:
       anweisung2;
       break;
   case constant3:
       anweisung3;
       break;
   default:   
       anweisung4;
}
Der ausdruck muss vom Typ byte, short, char oder int sein. Seit Java Version 7 darf auch ein String verwendet werden. Ist der Wert von ausdruck gleich constant1, so wird die anweisung1 und die anweisung2 ausgeführt. Hinter anweisung2 sorgt das break dafür, dass die weiteren Anweisungen nicht ausgeführt werden.

Der default-Zweig wird angesprungen, wenn keine der Konstanten dem switch-Ausdruck entspricht.

Das Beispiel mit dem Münzwert würde in einer Fallunterscheidung folgendermaßen aussehen:

switch (muenzwert) {
    case 200:
        // 2 Euro-Münze
        break;
    case 100:
        // 1 Euro-Münze
        break;
    case 50:
        // 50 Cent-Münze
        break;
    case 20:
        // 20 Cent-Münze
        break;
    case 10:
        // 10 Cent-Münze
        break;
    default:
        // Kleinvieh
}
Der Syntaxgraph für die Fallunterscheidung sieht so aus:

Korrekterweise müsste der Syntaxgraph so umgebaut werden, dass nur ein default-Zweig möglich ist. Allerdings wird er dadurch auch etwas unübersichtlich.

Mit Java 8 können auch Strings als Konstanten verwendet werden.

Mit Java 12 wird zusätzlich eine etwas sauberere Definition von switch angeboten. Dabei kann das break weggelassen werden, weil der

switch (ausdruck)
{
   case constant1,
        constant2
              -> anweisung2;
   case constant3
              -> anweisung3;
   default ->    anweisung4;
}

Hinzu kommt die Möglichkeit, switch als Ausdruck zu verwenden:

ergebnis = switch (ausdruck) {
    case constant1 -> ausdruck1;
    case constant2 -> ausdruck2;
    default -> ausdruck3;
};

Video


Kontrollstrukturen Bedingungen (boolesche Ausdrücke)