vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Woche 1

Tag 5


Arrays, Bedingungen und Schleifen

Wenn Sie ein Java-Programm mit dem Wissen geschrieben haben, das Sie bis zu diesem Zeitpunkt erworben haben, wird das wahrscheinlich etwas fade sein. Wenn Sie ein Java Programm mit dem Wissen geschrieben haben, das Sie bis zu diesem Zeitpunkt erworben haben, wird das wahrscheinlich etwas fade sein.

Daß der vorige Satz zweimal hintereinander auftaucht, ist kein Fehler. Dies soll demonstrieren, wie einfach es Computer machen, die gleiche Sache immer zu wiederholen. Sie werden heute lernen, wie Sie einen Teil eines Java-Programms mit Schleifen wiederholt ausführen lassen.

Zusätzlich werden Sie lernen, wie Sie ein Programm dazu bringen, basierend auf einer vorgegebenen Logik zu entscheiden, ob es etwas tun soll. (Vielleicht würde ein Computer entscheiden, daß es nicht besonders logisch ist, in einem Buch denselben Satz zweimal in Folge zu drucken.)

Sie werden auch lernen, in Ihren Programmen Variablengruppen derselben Klasse oder desselben Datentyps in Listen, die als Arrays bezeichnet werden, zu organisieren.

Als erstes stehen die Arrays auf der heutigen Aufgabenliste. Als erstes stehen die Arrays auf der heutigen Aufgabenliste.

Arrays

Bisher hatten Sie es in den einzelnen Java-Programmen nur mit wenigen Variablen zu tun. In vielen Fällen ist es machbar, Informationen in unabhängigen Variablen zu speichern.

Was wäre allerdings, wenn Sie 20 Elemente verwandter Information hätten, die Sie alle speichern müßten? Sie könnten 20 einzelne Variablen erstellen und deren Anfangswert festlegen. Diese Vorgehensweise wird aber immer ungeeigneter, je größer die Menge der Informationen wird, mit der Sie arbeiten. Was wäre, wenn es 100 oder gar 1000 Elemente wären?

Arrays stellen eine Methode zur Speicherung einer Reihe von Elementen, die alle denselben primitiven Datentyp oder dieselbe Klasse aufweisen. Jedem Element wird innerhalb des Arrays ein eigener Speicherplatz zugewiesen. Diese Speicherplätze sind numeriert, so daß Sie auf die Informationen leicht zugreifen können.

Arrays können jede Art von Information enthalten, die auch in einer Variablen gespeichert werden kann. Sobald ein Array aber erzeugt wurde, können Sie es nur noch für diesen einen Informationstyp verwenden. Sie können z.B. ein Array für Integer, eines für String-Objekte oder eines für Arrays erzeugen. Es ist aber nicht möglich, ein Array zu erstellen, das sowohl Strings als auch Integer beinhaltet.

Java implementiert Arrays anders als andere Programmiersprachen, nämlich als Objekte, die wie andere Objekte auch behandelt werden können.

Um in Java ein Array zu erzeugen, müssen Sie folgendes tun:

1. Deklarieren einer Variablen zur Aufnahme des Arrays

2. Erstellen eines neuen Array-Objekts und Zuweisen einer Array-Variablen

3. Speichern von Elementen im Array

Deklarieren von Array-Variablen

Der erste Schritt beim Anlegen eines Arrays ist das Deklarieren einer Variablen, die das Array aufnimmt. Das geschieht genauso wie bei anderen Variablen. Array-Variablen wird ein Typ zugewiesen, den das Array aufnimmt (wie bei jeder Variablen), und der Name des Arrays. Um das Ganze von einer normalen Variablendeklaration zu unterscheiden, wird noch ein Paar leerer eckiger Klammern ([]) an den Datentyp bzw. den Klassennamen oder den Namen des Arrays angefügt.

Nachfolgend typische Deklarationen von Array-Variablen:

String difficultWords[];
Point hits[];
int temps[];

Alternativ kann eine Array-Variable definiert werden, indem die Klammern nicht nach der Variablen, sondern nach dem Typ eingefügt werden. Die obigen drei Deklarationen würden nach dieser Methode so aussehen:

String[] difficultWords;
Point[] hits;
int[] temps;

Sie werden beide Stile in Programmen sehen. Es gibt keinen Konsens darüber, welcher Stil besser lesbar ist, so daß es den persönlichen Vorlieben überlassen bleibt, eine Form zu wählen.

Erstellen von Array-Objekten

Im zweiten Schritt wird ein Array-Objekt erstellt und dieser Variablen zugewiesen. Das kann auf zwei Arten erfolgen:

Da Arrays in Java Objekte sind, können Sie den Operator new verwenden, um eine neue Instanz eines Arrays zu erstellen:

String[] names = new String[10];

Diese Anweisung erstellt ein neues Array von Strings mit zehn Elementen. Beim Erstellen eines neuen Array-Objekts mit new müssen Sie angeben, wie viele Elemente das Array aufnehmen soll. Diese Anweisung fügt keine String-Objekte in das Array ein - das müssen Sie später selbst erledigen.

Array-Objekte können primitive Typen wie Ganzzahlen oder boolesche Werte genauso wie Objekte enthalten:

int[] temps = new int[99];

Beim Erstellen eines Array-Objekts mit new werden alle Elemente des Arrays automatisch initialisiert (0 für numerische Arrays, false für boolesche, '\0' für Zeichen-Arrays und null für alle anderen).

Sie können ein Array auf die gleiche Weise erstellen und initialisieren. Anstelle der Verwendung von new schließen Sie die Elemente des Arrays in Klammern ein und trennen sie durch Kommas:

String[] chiles = { "jalapeno", "anaheim", "serrano", "habanero", "thai" };

Beachten Sie bitte, daß das Schlüsselwort null von Java sich auf das Null-Objekt bezieht (und für eine beliebige Objektreferenz verwendet werden kann). Es ist allerdings nicht äquivalent mit 0 oder '0/' (Null-Zeichen), wie es bei der Konstante NULL in C der Fall ist.

Alle innerhalb der Klammern stehenden Elemente müssen vom gleichen Typ sein, der dem Typ der Variablen entsprechen muß, die das Array enthält. Ein Array wird automatisch mit der Zahl der Elemente, die Sie angegeben haben, erstellt. Dieses Beispiel erstellt ein Array mit String-Objekten namens chiles, das fünf Elemente enthält.

Zugreifen auf Array-Elemente

Nachdem Sie ein Array mit Anfangswerten erstellt haben, können Sie es testen und die Werte der einzelnen Zellen des Arrays ändern. Auf den Wert eines Elements in einem Array greifen Sie über den Array-Namen, gefolgt von einem Index in eckigen Klammern, zu. Diese Kombination aus Name und Index kann in Ausdrücken verwendet werden:

contestantScore[40] = 470;

Der Teil contestantScore dieses Audrucks ist eine Variable, die ein Array-Objekt beinhaltet, kann aber auch ein Ausdruck sein, der ein Array zurückgibt. Der Index legt das Element des Arrays, auf das zugegriffen wird, fest. Dies kann ebenfalls ein Ausdruck sein. Array-Indizes beginnen mit 0 wie in C und C++. Ein Array mit zehn Elementen hat folglich Index-Werte von 0 bis 9.

Alle Array-Indizes werden geprüft, um sicherzustellen, daß sie sich innerhalb der Grenzen des Arrays befinden, wie diese bei der Erzeugung des Arrays festgelegt wurden. In Java ist es unmöglich, auf einen Wert in einem Arrray-Element außerhalb dieser Grenzen zuzugreifen bzw. in einem solchen Element einen Wert zu speichern. Dadurch werden Probleme vermieden, wie sie beim Überschreiten von Array-Grenzen in Sprachen wie z.B. C entstehen. Betrachten Sie einmal die folgenden zwei Anweisungen:

String[] beatleSpeak = new String[10];
beatleSpeak[10] = "I am the eggman.";

Ein Programm, das die beiden vorigen Zeilen enthalten würde, würde einen Compiler- Fehler erzeugen, wenn beatleSpeak[10] verwendet wird. Der Fehler tritt auf, da beatleSpeak kein Element mit dem Index 10 hat - es verfügt zwar über 10 Elemente, die Index-Werte beginnen aber bei 0 und enden bei 9. Der Java-Compiler fängt diesen Fehler ab.

Wird der Array-Index zur Laufzeit berechnet (z.B. als Teil einer Schleife) und endet er außerhalb der Array-Grenzen, erzeugt der Java-Interpreter ebenfalls einen Fehler (um technisch korrekt zu sein, tritt eine Ausnahme auf). Sie lernen übernächste Woche am 17. Tag mehr über Ausnahmen.

Wie kann man verhindern, daß ein Programm versehentlich die Grenzen eines Arrays überschreitet? Sie können die Länge eines Arrays in Ihren Programmen mit der Instanzvariablen length testen. Sie ist für alle Array-Objekte, ungeachtet des Typs, verfügbar:

int len = beatleSpeak.length; // gibt 10 aus

Um es noch einmal zu sagen: Die Länge des Arrays ist 10, die Index-Werte gehen allerdings nur bis 9. Bei Arrays beginnt die Numerierung mit 0. Behalten Sie dies immer im Hinterkopf, wenn Sie mit Arrays arbeiten, und ziehen Sie 1 von der Länge des Arrays ab, um auf das letzte Element darin zuzugreifen.

Ändern von Array-Elementen

Wie Sie in den vorangegangenen Beispielen gesehen haben, setzen Sie einfach eine Zuweisungsanweisung hinter den Namen des Arrays mit dem Index des Elements in eckigen Klammern, um einer bestimmten Array-Zelle einen Wert zuzuweisen:

myGrades[4] = 85;
sentence[0] = "The";
sentence[10] = sentence[0];

Wichtig ist hier die Feststellung, daß ein Array mit Objekten in Java Referenzen auf diese Objekte enthält (ähnlich wie ein Pointer-Array in C oder C++). Wenn Sie einem Array-Element in einem derartigen Array einen Wert zuweisen, erstellen Sie eine Referenz auf das betreffende Objekt wie bei einer einfachen Variablen. Verschieben Sie Werte in Arrays (wie beispielsweise in der letzten Zeile oben), weisen Sie die Referenz erneut zu. Sie kopieren also nicht den Wert von einem Element in ein anderes. Arrays mit primitiven Typen wie int oder float kopieren dagegen die Werte von einem Element in ein anderes.

Arrays sind einfach zu erstellen, und ihr Inhalt ist leicht zu verändern. Für Java bieten Sie eine enorme Funktionalität. Sie werden feststellen, daß, je stärker Sie die Sprache einsetzen, Sie um so mehr mit Arrays arbeiten werden.

Um die Besprechung der Arrays abzuschließen, zeigt Listing 5.1 ein einfaches Programm, das zwei Arrays erzeugt, initialisiert, verändert und den Inhalt ausgibt.

Listing 5.1: Der gesamte Quelltext von ArrayTest.java

 1: class ArrayTest {
 2:
 3:     String[] firstNames = { "Dennis", "Grace", "Bjarne", "James" };
 4:     String[] lastNames = new String[firstNames.length];
 5:
 6:     void printNames() {
 7:         int i = 0;
 8:         System.out.println(firstNames[i]
 9:             + " " + lastNames[i]);
10:         i++;
11:         System.out.println(firstNames[i]
12:             + " " + lastNames[i]);
13:         i++;
14:         System.out.println(firstNames[i]
15:             + " " + lastNames[i]);
16:         i++;
17:         System.out.println(firstNames[i]
18:             + " " + lastNames[i]);
19:     }
20:
21:     public static void main (String arguments[]) {
22:         ArrayTest a = new ArrayTest();
23:         a.printNames();
24:         System.out.println("-----");
25:         a.lastNames[0] = "Ritchie";
26:         a.lastNames[1] = "Hopper";
27:         a.lastNames[2] = "Stroustrup";
28:         a.lastNames[3] = "Gosling";
29:         a.printNames();
30:     }
31: }

Das Program erzeugt die folgende Ausgabe:

Dennis null
Grace null
Bjarne null
James null
-----
Dennis Ritchie
Grace Hopper
Bjarne Stroustrup
James Gosling

Dieses längere Beispiel zeigt, wie Arrays erzeugt und verwendet werden. Die Klasse, die hier erstellt wird, ArrayTest, besitzt zwei Instanzvariablen, die je ein Array mit String-Objekten aufnehmen. Das erste, das den Namen firstNames trägt, wird in Zeile 3 mit vier Elementen initialisiert. Die zweite Instanzvariable, lastNames, wird in Zeile 4 deklariert. In dieses Array werden aber keine Werte eingefügt. Beachten Sie bitte, daß das Array lastNames exakt dieselbe Länge aufweist wie das Array firstNames , da hier bei der Erzeugung des Arrays die Variable firstNames.length als Größenangabe für das neue Array verwendet wurde. Die Instanzvariable length von Array-Objekten beinhaltet die Anzahl der Elemente eines Arrays.

Die Klasse ArrayTest (sie besitzt auch zwei Methoden: printNames() und main(). printNames()), die in den Zeilen 6 bis 19 definiert wird, ist eine Hilfsmethode, die die einzelnen Elemente der Arrays firstNames und lastNames durchgeht und deren Werte anzeigt. Beachten Sie hierbei bitte, daß hier der Array-Index (i) anfangs auf 0 gesetzt wird, da die Numerierung bei Java-Arrays mit 0 beginnt.

Die main()-Methode führt schließlich die folgenden Aufgaben aus:

Wenn Sie die Namen in diesem Beispiel nicht erkennen, dann könnten Sie eventuell denken, daß die Autoren Referenzen auf ihre Freunde in dieses Buch einbringen. Alle Namen sind Namen von Erfindern, die die führenden Entwickler von Computer-Programmiersprachen sind: Dennis Ritchie (C), Bjarne Stroustrup (C++), Grace Hopper (COBOL) und James Gosling (Java).

Eine letzte Anmerkung gilt es zu Listing 5.1 zu machen: Es ist ein Beispiel für furchtbar schlechten Programmierstil. Normalerweise verwenden Sie Schleifen, um die einzelnen Elemente eines Arrays durchzugehen, anstatt jedes Element einzeln zu behandeln. Dadurch wird der Code wesentlich kürzer und in vielen Fällen einfacher zu lesen. Wenn Sie später am heutigen Tag die Schleifen kennenlernen, werden Sie eine überarbeitete Version des aktuellen Beispiels sehen.

Mehrdimensionale Arrays

Wenn Sie Arrays bereits in anderen Programmiersprachen verwendet haben, werden Sie sich vielleicht fragen, ob Java mehrdimensionale Arrays unterstützt. Dies sind Arrays, die über mehr als einen Index verfügen, um mehrere Dimensionen zu repräsentieren.

Mehrere Dimensionen sind z.B. praktisch, um eine (x,y)-Tabelle als Array anzulegen.

In Java werden multidimensionale Arrays nicht unterstützt. Allerdings können Sie ein Array mit Arrays (die wiederum Arrays enthalten können usw., über beliebig viele Dimensionen) deklarieren:

int coords[] [] = new int[12][12];
coords[0][0] = 1;
coords[0][1] = 2;

Blockanweisungen

Anweisungen werden in Java in Blocks zusammengefaßt. Der Anfang und das Ende eines Blocks werden mit geschweiften Klammern ({}) gekennzeichnet.

Sie haben bis hierher bereits Blocks in den Programmen für die folgenden Aufgaben verwendet:

Blocks werden auch als Blockanweisungen bezeichnet, da ein gesamter Block überall dort verwendet werden könnte, wo auch eine einzelne Anweisung verwendet werden kann. Die Anweisungen in einem Block werden von oben nach unten ausgeführt.

Blocks können sich innerhalb anderer Blocks befinden, wie das der Fall ist, wenn Sie eine Methode in eine Klassendefinition einfügen.

Einen wichtigen Punkt gibt es zu Blocks anzumerken: Ein Block erzeugt einen sogenannten Gültigkeitsbereich für lokale Variablen, die in dem Block erzeugt werden.


Gültigkeitsbereich ist in der Programmierung der Begriff für den Teil eines Programms, in dem eine Variable existiert und verwendet werden kann. Wenn das Programm den Gültigkeitsbereich einer Variablen verläßt, dann existiert diese nicht, und es treten Fehler auf bei dem Versuch, auf diese zuzugreifen.

Der Gültigkeitsbereich einer Variablen ist der Block, in dem sie erzeugt wurde. Wenn Sie in einem Block lokale Variablen deklarieren und verwenden, dann hören diese Variablen auf zu existieren, sobald der Block ausgeführt ist. Die folgende Methode testBlock() beinhaltet z.B. einen Block:

void testBlock() {
    int x = 10;
    { // Beginn des Blocks
      int y = 40;
    y = y + x;
    } // Ende des Blocks
}

In dieser Methode werden zwei Variablen definiert: x und y. Der Gültigkeitsbereich der Variablen y ist der Block, in dem sie sich befindet, und sie kann auch nur in diesem angesprochen werden. Wenn Sie versuchen würden, sie in einem anderen Teil der Methode testBlock() zu verwenden, würde ein Fehler auftreten. Die Variable x wurde innerhalb der Methode, aber außerhalb des inneren Blocks definiert, so daß sie in der gesamten Methode angesprochen werden kann.

Blöcke werden normalerweise aber nicht auf diese Weise - allein in einer Methodendefinition - verwendet, wie das im vorigen Beispiel der Fall war. Vorwiegend haben Sie bisher Blöcke gesehen, die Klassen- und Methodendefinitionen umgeben. Daneben gibt es eine andere häufige Verwendung für Blockanweisungen in logischen Strukturen und Schleifen, über die Sie später in der heutigen Lektion mehr erfahren.

if-Bedingungen

Einer der wesentlichen Aspekte bei der Programmierung ist die Möglichkeit für ein Programm, zu entscheiden, was es tun soll. Dies wird durch eine bestimmte Anweisungsart, die Bedingung genannt wird, erreicht.


Eine Bedingung ist eine Programmanweisung, die nur dann ausgeführt wird, wenn eine bestimmte Situation eintritt.

Die elementarste Bedingung wird mit dem Schlüsselwort if erzeugt. Eine if-Bedingung verwendet einen booleschen Ausdruck, um zu entscheiden, ob eine Anweisung ausgeführt werden soll. Wenn der Ausdruck true zurückliefert, wird die Anweisung ausgeführt.

Hier nun ein einfaches Beispiel, das die Nachricht "You call that a haircut?" (zu deutsch: »Sie bezeichnen das als einen Haarschnitt?«) nur unter einer Bedingung ausgibt: Der Wert der Variablen age ist größer als 39:

if (age > 39)
    System.out.println("You call that a haircut?");

Wenn Sie wollen, daß etwas passiert, wenn der boolesche Ausdruck false zurückgibt, dann verwenden Sie das optionale Schlüsselwort else. Das folgende Beispiel verwendet sowohl if als auch else:

if (blindDateIsAttractive == true)
    restaurant = "Benihana's";
else
    restaurant = "Burrito Hut";

Die if-Anweisung führt hier anhand des Ergebnisses des booleschen Ausdrucks in der if-Anweisung unterschiedliche Anweisungen aus.


Zwischen den if-Anweisungen von Java und C/C++ gibt es folgenden Unterschied: Der Testausdruck in der if-Anweisung muß in Java einen booleschen Wert zurückgeben (true oder false). In C kann der Test auch einen Integer zurückgeben.

Wenn Sie eine if-Anweisung verwenden, ist es möglich, lediglich eine einzige Anweisung nach dem Testausdruck ausführen zu lassen (im vorigen Beispiel wurde der Variablen restaurant ein Wert zugewiesen). Da aber ein Block überall dort verwendet werden kann, wo auch eine einzelne Anweisung stehen kann, können Sie, wenn Sie mehr als nur eine Anweisung ausführen wollen (was normalerweise der Fall ist), diese Anweisungen zwischen ein Paar geschweifter Klammern setzen. Sehen Sie sich einmal das folgende Code-Schnipsel an, das eine Erweiterung des Jabberwock-Objekts von Tag 2 ist:

if (attitude == "angry" ) {
    System.out.println("The jabberwock is angry.");
    System.out.println ("Have you made out a will?");
} else {
    System.out.println ("The jabberwock is in a good mood.");
    if (hungry)
        System.out.println("It still is hungry, though.");
    else System.out.println("It wanders off.");
}

In diesem Beispiel wird der Testausdruck (attitude == "angry") verwendet. Dadurch soll festgestellt werden, ob das Jabberwock zornig oder in guter Stimmung ist. Wenn das Jabberwock guter Dinge ist, wird mit dem Testausdruck (hungry) geprüft, ob das Jabberwock hungrig ist - davon ausgehend, daß man ein hungriges Jabberwock, auch wenn es gut gelaunt ist, meiden sollte. Die Bedingung if (hungry) ist eine andere Form des Ausdrucks if (hungry == true). Für boolesche Testausdrücke dieser Art, ist es bei der Programmierung üblich, den letzten Teil des Ausdrucks wegzulassen.

Listing 5.2 ist ein weiteres einfaches Beispiel - diesmal in Form einer vollständigen Applikation. Die Klasse EvenSteven beinhaltet eine Hilfsmethode mit dem Namen checkEven(), die überprüft, ob ein Wert gerade ist. Ist dies der Fall, gibt sie Steven auf den Bildschirm aus.

Listing 5.2: Der gesamte Quelltext von EvenSteven.java

 1: class EvenSteven {
 2:
 3:     void evenCheck(int val) {
 4:         System.out.println("Value is "
 5:             + val + ". ");
 6:         if (val % 2 == 0)
 7:         System.out.println("Steven!");
 8:     }
 9:
10:     public static void main (String arguments[]) {
11:         EvenSteven e = new EvenSteven();
12:
13:         e.evenCheck(1);
14:         e.evenCheck(2);
15:         e.evenCheck(54);
16:         e.evenCheck(77);
17:         e.evenCheck(1346);
18:     }
19: }

Das Programm liefert die folgende Ausgabe:

Value is 1.
Value is 2.
Steven!
Value is 54.
Steven!
Value is 77.
Value is 1346.
Steven!

Das Herz der Klasse EvenSteven ist die Methode checkEven() (Zeilen 3 bis 8). Hier werden die Werte geprüft und die entsprechenden Nachrichten ausgegeben. Anders als bei den Methoden, die Sie in den vorangegangenen Beispielen definiert haben, verwendet die Methode checkEven() ein Integer-Argument (siehe Zeile 3). Die Methode checkEven() beginnt damit, den Wert, der ihr übergeben wurde, auszugeben. Anschließend wird das Argument mit einer if-Bedingung getestet, um zu sehen, ob es sich um eine gerade Zahl handelt.

Der Test mit dem Modulo-Operator ergibt, wie Sie sich sicherlich von Tag 3 her erinnern werden, den Rest der Division der Operanden. Wenn der Rest der Division einer Zahl durch 2 0 ergibt, dann ist diese Zahl gerade.

Wenn eine Zahl gerade ist, wird "Steven!" angezeigt (Sie lernen morgen mehr darüber, wie Sie Methoden mit Argumenten definieren).

Die main()-Methode dieser Applikation erzeugt eine neue Instanz der Klasse EvenSteven und prüft diese, indem sie die Methode checkEven() wiederholt mit unterschiedlichen Werten aufruft. In der Ausgabe haben nur die geraden Werte die Nachricht "Steven!".

Der Bedingungsoperator

Eine Alternative zur Verwendung der Schlüsselwörter if und else in einer Bedingungsanweisung ist der Bedingungsoperator, der auch ternärer Operator genannt wird. Der Bedingungsoperator ist ein ternärer Operator, weil er drei Teile umfaßt.

Der Bedingungsoperator ist ein Ausdruck, was bedeutet, daß er einen Wert zurückgibt (im Gegensatz zum allgemeineren if, das zur Ausführung einer beliebigen Anweisung oder eines Blocks führen kann). Der Bedingungsoperator ist besonders für sehr kurze oder einfache Bedingungen nützlich und sieht so aus:

Test ? trueresult : falseresult

Das Wort Test ist ein Ausdruck, der true oder false ausgibt, wie beim Testen in der if-Anweisung. Ist der Test true, gibt der Bedingungsoperator den Wert von trueresult aus. Ist er false, gibt er den Wert von falseresult aus. Folgende Bedingung prüft z.B. die Werte von myScore und yourScore, gibt den kleineren der beiden Werte aus und weist diesen Wert der Variablen ourBestScore zu:

int ourBestScore = myScore > yourScore ? myScore : yourScore;

Diese Zeile mit dem Bedingungsoperator entspricht dem folgenden If-Else-Konstrukt:

if (myScore > yourScore)
    ourBestScore = myScore;
else
    ourBestScore = yourScore;

Der Bedingungsoperator hat eine sehr niedrige Präzedenz. Das bedeutet, daß er normalerweise erst nach allen Unterausdrücken ausgewertet wird. Nur die Zuweisungsoperatoren haben eine noch niedrigere Präzedenz. Zum Auffrischen des Gedächtnisses können Sie die Präzedenz von Operatoren in der Tabelle 3.6 von Tag 3 nachschlagen.

switch-Bedingungen

Eine übliche Vorgehensweise beim Programmieren in jeder Sprache ist das Testen einer Variablen auf einen bestimmten Wert. Falls sie nicht zu diesem Wert paßt, wird sie anhand eines anderen Wertes geprüft, und falls dieser wieder nicht paßt, wird wieder mit einem anderen Wert geprüft usw. Werden nur if-Anweisungen verwendet, kann das je nachdem, wie der Quelltext dabei formatiert wurde und wie viele verschiedene Optionen geprüft werden müssen, sehr unhandlich sein. Zum Schluß erhalten Sie if- Anweisungen wie im folgenden Beispiel oder noch unhandlicher:

if (oper == '+')
addargs(arg1,arg2);
else if (oper == '=')
subargs(arg1,arg2);
else if (oper == '*')
multargs(arg1,arg2);
else if (oper == '/')
divargs(arg1,arg2);

Diese Form nennt man verschachtelte if-Anweisungen, weil jede else-Anweisung ihrerseits weitere if-Anweisungen enthält, bis alle möglichen Tests ausgeführt wurden.

Eine übliche Kurzform anstelle verschachtelter if-Anweisungen ermöglicht Ihnen in manchen Fällen, Tests und Aktionen gemeinsam in einer Anweisung auszuführen. Das ist die Anweisung switch oder case. In Java ist es die Anweisung switch, die sich wie in C verhält:

switch (grade) {
    case 'A':
        System.out.println("Great job -- an A!");
        break;
    case 'B':
        System.out.println("Good job -- a B!");
        break;
    case 'C':
        System.out.println("Your grade was a C.");
        break;
    default: System.out.println("An F -- consider cheating!");
}

Die switch-Anweisung basiert auf einem Test; im vorigen Beispiel wird der Wert der Variablen gerade getestet. Die Testvariable, die einen der primitiven Typen byte, char, short oder int aufweisen kann, wird nacheinander mit jedem der case-Werte verglichen. Wenn eine Übereinstimmung gefunden wird, wird (werden) die Anweisung(en) im Anschluß an den case-Wert ausgeführt. Wenn keine Übereinstimmung gefunden wird, wird (werden) die Anweisung(en) des default-Zweiges ausgeführt. Sollte dieser nicht vorhanden sein und wird auch keine Übereinstimmung gefunden, dann wird die switch-Anweisung beendet, ohne daß irgend etwas ausgeführt wird.

Die Java-Implementierung von switch ist einigen Einschränkungen unterworfen - der Testwert und die Werte der case-Zweige dürfen nur primitive Typen aufweisen, die sich in den Typ int casten lassen. Sie können keine größeren primitiven Typen verwenden, wie z.B. long oder float, Strings oder andere Objekte. Auch können Sie nur auf Gleichheit und keine anderen Relationen testen. Diese Grenzen beschränken die switch-Anweisung auf sehr einfache Fälle. Im Gegensatz dazu können verschachtelte if-Anweisungen mit allen Testmöglichkeiten und allen Datentypen arbeiten.

Hier noch einmal das obige Beispiel, diesmal jedoch mit einer switch-Anweisung anstelle verschachtelter if-Anweisungen:

switch (oper) {
case '+':
addargs(arg1,arg2);
break;
case '*':
subargs(arg1,arg2);
break;
case '-':
multargs(arg1,arg2);
break;
case '/':
divargs(arg1,arg2);
break;
}

In diesem Beispiel gibt es zwei Dinge, die Sie beachten sollten: Erstens können Sie nach jeder case-Anweisung eine einzelne Anweisung oder so viele Anweisungen, wie eben nötig, schreiben. Anders als bei der if-Anweisung müssen Sie keine geschweiften Klammern verwenden, wenn Sie mehrere Anweisungen angeben. Zweitens sollten Sie die break-Anweisung, die sich in diesem Beispiel in jedem der case-Zweige befindet, beachten. Ohne die break-Anweisung würden, sobald eine Übereinstimmung gefunden wird, alle Anweisungen für diese Übereinstimmung und alle Anweisungen, die diesen Anweisungen folgen, ausgeführt. Dies geht so lange, bis eine break-Anweisung auftaucht oder das Ende der switch-Aweisung erreicht ist. In einigen Fällen kann dies genau das sein, was Sie wollen. In den meisten Fällen sollten Sie eine break-Anweisung einfügen, um sicherzustellen, daß nur der richtige Code ausgeführt wird. Die break-Anweisung, worüber Sie im Abschnitt »Schleifen verlassen« mehr lernen werden, bricht die Ausführung an der aktuellen Stelle ab und springt zu dem Code im Anschluß an die nächste schließende geschweifte Klammer (}).

Eine gute Anwendung, bei der Sie die break-Anweisung weglassen, ist, wenn mehrere Werte die gleiche(n) Anweisung(en) ausführen sollen. In diesem Fall können Sie mehrere case-Zweige ohne Anweisungen eingeben, dann führt switch die ersten Anweisungen aus, die es findet. In der folgenden switch-Anweisung wird beispielsweise die Zeichenkette "x is an even number." ausgegeben, wenn x einen geraden Wert, z.B. 2, 4, 6 oder 8, hat. Alle anderen Werte von x geben die Zeichenkette "x is an odd number." aus.

switch (x) {
case 2:
case 4:
case 6:
case 8:
System.out.println("x is an even number.");
break;
default: System.out.println("x is an odd number.");
}

Das Listing 5.3 zeigt noch ein weiteres Beispiel für die Verwendung der switch-Anweisung. Diese Klasse mit dem Namen NumberReader konvertiert Ziffern in das englische Wort, das der Ziffer entspricht. Dazu wird die Methode convertIt() verwendet.

Listing 5.3: Der gesamte Quelltext von NumberReader.java

 1: class NumberReader {
 2:
 3:     String convertNum(int val) {
 4:         switch (val) {
 5:             case 0: return "zero ";
 6:             case 1: return "one ";
 7:             case 2: return "two ";
 8:             case 3: return "three ";
 9:             case 4: return "four ";
10:             case 5: return "five ";
11:             case 6: return "six ";
12:             case 7: return "seven ";
13:             case 8: return "eight ";
14:             case 9: return "nine ";
15:             default: return " ";
16:         }
17:     }
18:
19:     public static void main (String arguments[]) {
20:         NumberReader n = new NumberReader();
21:         String num = n.convertNum(4) + n.convertNum(1) + n.convertNum(3);
22:         System.out.println("413 converts to " + num);
23:     }
24: }

Das Programm liefert die folgende Ausgabe:

413 converts to four one three

Das Herz dieses Beispiels ist natürlich die switch-Anweisung in der Mitte der Methode convertNum() in den Zeilen 4 bis 16. Diese switch-Anweisung nimmt das Integer-Argument, das convertNum() übergeben wurde, und gibt, wenn sie eine Übereinstimmung findet, den entsprechenden String zurück. Dies steht im Gegensatz zu den anderen Methoden, die Sie bis zu diesem Zeitpunkt verwendet und die keinen Wert zurückgegeben haben. (Über diesen Punkt werden Sie morgen mehr lernen.)

In dem Programm NumberReader werden keine break-Anweisungen benötigt, statt dessen wird die return-Anweisung verwendet. return ist break ähnlich mit der Ausnahme, daß return die Methode komplett verläßt und einen Wert zurückgibt. Auch darüber erfahren Sie morgen mehr, wenn Sie lernen, wie Sie Methoden definieren.

Inzwischen haben Sie wahrscheinlich schon genügend main()-Methoden gesehen, um zu verstehen, was hier passiert. Trotzdem wollen wir diese hier kurz durchgehen.

In Zeile 20 wird eine neue Instanz der Klasse NumberReader erzeugt.

In Zeile 21 wird eine String-Variable mit dem Namen num definiert. Diese wird den verketteten String-Wert dreier Ziffern aufnehmen. Jede der Ziffern wird über einen Aufruf der Methode convertNum() konvertiert.

Und schließlich zeigt der Code in der Zeile 22 das Ergebnis an.

for-Schleifen

Wie in C wiederholt die for-Schleife eine Anweisung oder einen Anweisungsblock mehrmals, bis eine Bedingung zutrifft. for-Schleifen werden häufig für einfache Wiederholungen verwendet, um Blockanweisungen mehrmals auszuführen und dann zu stoppen. Sie können for-Schleifen für jede Schleifenart verwenden.

Die for-Schleife sieht in Java so aus:

for (Initialisierung; Test; Inkrement) {
Anweisungen;
}

Der Beginn der for-Schleife hat drei Teile:

Der Anweisungen-Teil der for-Schleife enthält die Anweisungen, die bei jeder Wiederholung der Schleife ausgeführt werden. Wie bei if können Sie hier entweder eine einzelne Anweisung oder einen Block einbinden. Im vorherigen Beispiel wurde ein Block benutzt, weil das üblich ist. Im nächsten Beispiel einer for-Schleife wird allen Elementen eines String-Arrays der Wert "Mr." zugewiesen:

String[] salutation = new String[10];
int i; // Schleifenindex

for (i = 0; i < salutation.length; i++)
    salutation[i] = "Mr.";

In diesem Beispiel überwacht die Variable i, wie oft die Schleife bereits durchlaufen wurde. Gleichzeitig stellt sie auf bequeme Weise einen Index für das Array dar. Wir starten die for-Schleife mit i = 0. Der Test, ob die Schleife beendet werden soll, prüft, ob der aktuelle Index kleiner als die Länge des Arrays ist (sobald der Index größer als das Array lang ist, sollten Sie die Schleife beenden). Das Inkrement fügt dem Index bei jedem Schleifendurchlauf 1 hinzu. So können Sie bei jeder Iteration der Schleife dem Element mit dem aktuellen Index den Wert "Mr." zuweisen.

Jeder Teil der for-Schleifendeklaration kann eine leere Anweisung sein, d.h., Sie können einfach ein Semikolon ohne Ausdruck oder Anweisung eingeben, dann wird dieser Teil der for-Schleife ignoriert. Wenn Sie in einer for-Schleife eine leere Anweisung verwenden, müssen Sie eventuell Schleifenvariablen oder Schleifenindizes manuell anderswo im Programm initialisieren oder inkrementieren.

Auch im Körper der for-Schleife kann eine leere Anweisung stehen, falls alles, was Sie bezwecken, in der ersten Zeile der Schleife steht. Im folgenden Beispiel wird die erste Primzahl gesucht, die größer ist als 4000 (dafür wird in der Schleifendeklaration die Methode notPrime() aufgerufen, die in der Lage sein soll zu prüfen, ob eine Zahl eine Primzahl ist):

for (i = 4001; notPrime(i); i += 2)
;

Beachten Sie, daß ein häufig in C gemachter Fehler auch in Java passieren kann: Nach der ersten Zeile der for-Schleife wird versehentlich ein Semikolon eingegeben:

for (i = 0; i < 10; i++);
    x = x * i; // diese Zeile befindet sich nicht innerhalb der Schleife

Das erste Semikolon beendet die Schleife mit einer leeren Anweisung, ohne daß x = x * i in der Schleife ausgeführt wird. Die Zeile x = x * i wird nur einmal ausgeführt, weil sie sich außerhalb der for-Schleife befindet. Achten Sie darauf, daß Ihnen dieser Fehler in Ihren Java-Programmen nicht passiert.

Am Ende des Abschnitts über die for-Schleifen wollen wir das Beispiel mit den Namen aus dem Abschnitt über die Arrays neu schreiben. Der Original-Quelltext ist lang und wiederholt sich. Außerdem arbeitet das Programm in dieser Version nur mit einem Array mit vier Elementen. Diese Version (siehe Listing 5.4) ist kürzer und wesentlich flexibler (erzeugt aber dieselbe Ausgabe).

Listing 5.4: Der gesamte Quelltext von NamesLoop.java

 1: class NamesLoop {
 2:
 3:     String[] firstNames = { "Dennis", "Grace", "Bjarne", "James" };
 4:     String[] lastNames = new String[firstNames.length];
 5:
 6:     void printNames() {
 7:         for (int i = 0; i < firstNames.length; i++)
 8:             System.out.println(firstNames[i] + " " + lastNames[i]);
 9:         }
10:
11:     public static void main (String arguments[]) {
12:         NamesLoop a = new NamesLoop();
13:         a.printNames();
14:         System.out.println("-----");
15:         a.lastNames[0] = "Ritchie";
16:         a.lastNames[1] = "Hopper";
17:         a.lastNames[2] = "Stroustrup";
18:         a.lastNames[3] = "Gosling";
19:
20:         a.printNames();
21:     }
22: }

Das Program erzeugt die folgende Ausgabe:

Dennis null
Grace null
Bjarne null
James null
-----
Dennis Ritchie
Grace Hopper
Bjarne Stroustrup
James Gosling

Der einzige Unterschied zwischen diesem Beispiel und dem Listing 5.1 findet sich in der Methode printNames(). Anstatt die Elemente des Arrays einzeln anzusprechen, verwendet dieses Beispiel eine for-Schleife, um das Array Element für Element durchzugehen und beim letzten Element zu stoppen. Indem Sie eine etwas allgemeiner gestaltete Schleife verwenden, haben Sie die Möglichkeit, die printNames()-Methode für jedes Array mit beliebiger Größe zu verwenden und gleichzeitig alle darin befindlichen Elemente auszugeben.

while- und do-Schleifen

Nun bleiben noch die Schleifenarten while und do zu erlernen. Wie mit for-Schleifen kann mit while- und do-Schleifen ein Java-Code-Block wiederholt ausgeführt werden, bis eine bestimmte Bedingung erfüllt ist. Welche der drei Schleifenarten (for, while oder do) Sie bevorzugt verwenden, ist eine Sache des persönlichen Programmierstils.

Die Schleifen while und do sind mit denen in C und C++ identisch, mit dem Unterschied, daß die Testbedingung in Java boolesch sein muß.

while-Schleifen

Die while-Schleife wird zum Wiederholen einer Anweisung oder von Blockanweisungen verwendet, solange eine bestimmte Bedingung zutrifft. Im Anschluß sehen Sie ein Beispiel für eine while-Schleife:

while (i < 10) {
    x = x * i++; // Rumpf der Schleife
}

Die Bedingung, die das Schlüsselwort while begleitet, ist ein boolescher Ausdruck - im vorigen Beispiel i < 10. Wenn der Ausdruck true ergibt, dann führt die while- Schleife den Rumpf der Schleife aus und prüft anschließend die Bedingung erneut. Dieser Prozeß wiederholt sich so lange, bis die Bedingung false ergibt. Obwohl die obige Schleife ein Paar geschweifter Klammern für eine Blockanweisung im Rumpf der Schleife verwendet, wären diese hier nicht nötig, da sich nur eine Anweisung darin befindet - x = x * i++. Die Klammern stellen aber kein Problem dar. Benötigt werden sie, wenn Sie später eine weitere Anweisung in den Rumpf der Schleife einfügen.

Das Listing 5.5 zeigt ein Beispiel für eine while-Schleife, die die Elemente eines Arrays mit Ganzzahlen (in array1) in ein Array mit Gleitpunktzahlen (in array2) kopiert. Dabei werden alle Elemente nacheinander in float konvertiert. Ist eines der Elemente im ersten Array 1, wird die Schleife sofort an diesem Punkt beendet.

Listing 5.5: Der gesamte Quelltext von CopyArrayWhile.java

 1: class CopyArrayWhile {
 2:     public static void main (String arguments[]) {
 3:         int[] array1 = { 7, 4, 8, 1, 4, 1, 4 };
 4:         float[] array2 = new float[array1.length];
 5:
 6:         System.out.print("array1: [ ");
 7:         for (int i = 0; i < array1.length; i++) {
 8:             System.out.print(array1[i] + " ");
 9:         }
10:         System.out.println("]");
11:
12:         System.out.print("array2: [ ");
13:         int count = 0;
14:         while ( count < array1.length && array1[count] != 1) {
15:             array2[count] = (float) array1[count];
16:             System.out.print(array2[count++] + " ");
17:         }
18:         System.out.println("]");
19:     }
20: }

Das Programm erzeugt die folgende Ausgabe:

array1: [ 7 4 8 1 4 1 4 ]
array2: [ 7.0 4.0 8.0 ]

Lassen Sie uns nun einen Blick darauf werfen, was in der main()-Methode vor sich geht:

Die Zeilen 3 und 4 deklarieren die Arrays. array1 ist ein Array für int-Werte, das ich mit irgendwelchen geeigneten Werten initialisiert habe. array2 ist vom Typ float, hat dieselbe Größe wie array1, wird aber nicht mit Werten initialisiert.

Die Zeilen 6 bis 10 dienen zur Ausgabe. Hier wird einfach array1 mit einer for- Schleife durchgegangen, und die einzelnen Werte darin werden auf dem Bildschirm ausgegeben.

In den Zeilen 13 bis 17 passieren die interessanten Dinge. Die Anweisung hier weist zugleich array2 die Werte zu (dafür werden die int-Werte in float-Werte konvertiert) und gibt sie auf dem Bildschirm aus. Wir beginnen mit der Variablen count, die den Array-Index darstellt. Der Testausdruck in der while-Schleife prüft zwei Bedingungen: Zum einen wird überwacht, ob das Ende des Arrays erreicht ist, und zum anderen, ob einer der Werte in array1 1 ist (wie Sie sich erinnern werden, war dies Teil der Beschreibung des Programms). Der Testausdruck läßt sich mit dem logischen UND-Operator && formen. Denken Sie bitte daran, daß der Operator && sicherstellt, daß beide Bedingungen true sind, bevor der gesamte Ausdruck true ergibt. Wenn einer davon false ist, ergibt der gesamte Ausdruck false, und die Schleife endet. Was passiert nun in diesem speziellen Beispiel? Die Ausgabe zeigt, daß die ersten vier Elemente von array1 in array2 kopiert wurden. Allerdings befand sich mitten unter den Werten eine 1, die die Ausführung der Schleife beendete. Ohne das Auftreten einer 1 sollte array2 am Ende dieselben Elemente beinhalten wie array1.

Falls die Bedingung beim ersten Durchlauf false ist (z.B. wenn das erste Element im ersten Array 1 ist), wird der Körper der while-Schleife nie ausgeführt. Soll die Schleife mindestens einmal ausgeführt werden, haben Sie folgende Möglichkeiten:

Die do-Schleife gilt als bessere Lösung der zwei Möglichkeiten.

do...while-Schleifen

Die do-Schleife entspricht der while-Schleife, außer daß sie eine bestimmte Anweisung oder einen Block so oft ausführt, bis eine Bedingung false ergibt. Auf den ersten Blick erscheinen die beiden Schleifentypen gleich. Der wesentliche Unterschied ist, daß while-Schleifen die Bedingung vor der Ausführung der Schleife prüfen, so daß der Schleifenkörper unter Umständen nie ausgeführt wird, wenn die Bedingung beim ersten Durchlauf false ist, während bei do-Schleifen der Schleifenkörper mindestens einmal vor dem Testen der Bedingung ausgeführt wird.

Der Unterschied ist in etwa so, wie beim Ausleihen des Autos der Eltern. Wenn man die Eltern fragt, bevor man das Auto ausleiht, und sie sagen nein, dann hat man das Auto nicht. Fragt man sie dagegen, nachdem man sich das Auto ausgeliehen hat, und sie sagen nein, dann hatte man das Auto bereits.

do-Schleifen sehen in Java so aus:

do {
    x = x * i++; // Rumpf der Schleife
} while (i < 10);

Der Rumpf der Schleife wird einmal ausgeführt, bevor die Bedingung i < 10 ausgewertet wird. Wenn der Test anschließend true ergibt, wird die Schleife erneut ausgeführt. Wenn der Test allerdings false ergibt, dann wird die Schleife beendet. Denken Sie immer daran, daß bei do-Schleifen der Rumpf der Schleife mindestens einmal ausgeführt wird.

Listing 5.6 zeigt ein einfaches Beispiel einer do-Schleife, die eine Nachricht bei jedem Durchlauf der Schleife ausgibt (in diesem Beispiel zehnmal):

Listing 5.6: Der gesamte Quelltext von DoTest.java

 1: class DoTest {
 2:     public static void main (String arguments[]) {
 3:         int x = 1;
 4:
 5:         do {
 6:             System.out.println("Looping, round " + x);
 7:             x++;
 8:         } while (x <= 10);
 9:     }
10: }

Im folgenden die Ausgabe des Programms:

Looping, round 1
Looping, round 2
Looping, round 3
Looping, round 4
Looping, round 5
Looping, round 6
Looping, round 7
Looping, round 8
Looping, round 9
Looping, round 10

Unterbrechen von Schleifen

Alle Schleifen (for, while und do) enden, wenn die geprüfte Bedingung erfüllt ist. Was passiert, wenn etwas Bestimmtes im Schleifenkörper stattfindet und Sie die Schleife bzw. die aktuelle Iteration frühzeitig beenden wollen? Hierfür können Sie die Schlüsselwörter break und continue verwenden.

Sie haben break bereits als Teil der switch-Anweisung kennengelernt. break stoppt die Ausführung von switch, und das Programm läuft weiter. Bei Verwendung mit einer Schleife bewirkt das Schlüsselwort break das gleiche - es hält die Ausführung der aktiven Schleife sofort an. Enthalten Schleifen verschachtelte Schleifen, wird die Ausführung mit der nächstäußeren Schleife wieder aufgenommen. Andernfalls wird die Ausführung des Programms ab der nächsten Anweisung nach der Schleife fortgesetzt.

Nehmen wir als Beispiel an, Sie haben eine while-Schleife, die Elemente von einem Array in ein anderes kopiert. Jedes Element im Array soll kopiert werden, bis das Ende des Arrays erreicht ist oder bis ein Element 1 ist. Sie können den zweiten Fall im while-Körper testen und dann break verwenden, um die Schleife zu beenden:

while (count < array1.length) {
if (array1[count] == 1) {
break;
}
array2[count] = (float) array1[count++];
}

continue verhält sich ähnlich wie break, außer, daß die Ausführung der Schleife nicht komplett gestoppt wird, sondern mit der nächsten Iteration erneut beginnt. Bei do- und while-Schleifen bedeutet das, daß die Ausführung des Blocks erneut beginnt. Bei for-Schleifen wird der Ausdruck Inkrement ausgewertet, dann wird der Block ausgeführt. continue ist nützlich, wenn Sie spezielle Fälle in einer Schleife berücksichtigen wollen. In dem vorherigen Beispiel, in dem ein Array in ein anderes kopiert wird, können Sie testen, ob das aktuelle Element 1 ist, und die Schleife neu starten, falls dies zutrifft. Dadurch erreichen Sie, daß das resultierende Array nie eine 1 enthält. Da dabei Elemente im ersten Array übersprungen werden, müssen Sie folglich die zwei verschiedenen Array-Zähler überwachen:

int count = 0;
int count2 = 0;
while (count < array1.length) {
if (array1[count] == 1){
        count++;
        continue;
     }
     array2[count2++] = (float)array1[count++];
}

Benannte Schleifen

Sowohl break als auch continue kann optional beschriftet werden, um Java mitzuteilen, wo genau die Ausführung wieder aufgenommen werden soll. Ohne Beschriftung springt break aus der innersten Schleife (zu der umgebenden Schleife oder zur nächsten Anweisung außerhalb der Schleife), während continue mit der nächsten Iteration des in Klammern stehenden Schleifenrumpfs beginnt. Durch Verwendung beschrifteter break- und continue-Anweisungen können Sie die Ausführung außerhalb von verschachtelten Schleifen oder eine Schleife außerhalb der aktiven Schleife fortsetzen.

Um eine Schleife zu benennen, fügen Sie vor dem Anfangsteil der Schleife eine Beschriftung (Label) und einen Doppelpunkt ein. Wenn Sie dann break oder continue verwenden, fügen Sie den Namen der Beschriftung direkt nach dem Schlüsselwort ein:

out:
    for (int i = 0; i <10; i++) {
        while (x < 50) {
            if (i * x++ > 400)
                break out;
            // innere Schleife
        }
        // äußere Schleife
    }

In diesem Codeteil wird die äußere for-Schleife mit out bezeichnet. Ein break innerhalb der for- und der while-Schleife veranlaßt die Unterbrechung beider Schleifen, falls eine bestimmte Bedingung in beiden Schleifen erfüllt ist, und startet wieder ab der Beschriftung (out).

Das folgende kleine Programm in Listing 5.7 ist ein weiteres Beispiel mit einer verschachtelten for-Schleife. Beide Schleifen werden sofort beendet, wenn die Summe der zwei Zähler in der innersten Schleife größer ist als vier:

Listing 5.7: Der gesamte Quelltext von LabelTest.java

 1: class LabelTest {
 2:     public static void main (String arguments[]) {
 3:
 4:     thisLoop:
 5:         for (int i = 1; i <= 5; i++)
 6:         for (int j = 1; j <= 3; j++) {
 7:             System.out.println("i is " + i + ", j is " + j);
 8:             if (( i + j) > 4)
 9:             break thisLoop;
10:         }
11:         System.out.println("end of loops");
12:     }
13: }

Die Ausgabe dieses Programms ist wie folgt:

i is 1, j is 1
i is 1, j is 2
i is 1, j is 3
i is 2, j is 1
i is 2, j is 2
i is 2, j is 3
end of loops

Wie Sie sehen, wird die Schleife so oft wiederholt, bis die Summe von i und j größer ist als 4, dann enden beide Schleifen, führen zum äußeren Block zurück und die endgültige Meldung wird ausgegeben.

Zusammenfassung

Sie haben gelernt, wie eine Array-Variable deklariert wird, wie ein Array-Objekt erstellt und dieser Variablen zugewiesen wird und wie Sie auf Elemente in einem Array zugreifen und diese ändern.

Zu Bedingungen zählen die Anweisungen if und switch, mit denen Sie auf der Grundlage eines booleschen Tests in andere Teile eines Programms verzweigen können.

Ferner haben Sie die Schleifen for, while und do gelernt. Mit allen drei Schleifenarten können Sie einen Programmteil wiederholt ausführen, bis eine bestimmte Bedingung erfüllt ist.

Das muß wiederholt werden:

Fragen und Antworten

Frage:
Ich habe in einer Blockanweisung für eine if-Anweisung eine Variable deklariert. Als die if-Anweisung verarbeitet war, verschwand die Definition dieser Variablen. Wie kann das sein?

Antwort:
Vom technischen Gesichtspunkt bilden Blockanweisungen innerhalb von Klammern einen neuen Gültigkeitsbereich. Das bedeutet, daß eine in einem Block deklarierte Variable nur innerhalb dieses Blocks sichtbar und nutzbar ist. Sobald die Ausführung des Blocks abgeschlossen ist, verschwinden alle Variablen, die Sie darin deklariert haben.

Es empfiehlt sich, Variablen im äußersten Block, in dem sie gebraucht werden, zu deklarieren. Das ist normalerweise am Anfang einer Blockanweisung. Eine Ausnahme hierzu können sehr einfache Variablen sein, z.B. Indexzähler in for-Schleifen, deren Deklaration in der ersten Zeile der for-Schleife eine einfache Kurzform ist.

Frage:
Warum kann man switch nicht mit Strings benutzen?

Antwort:
Strings sind Objekte, während switch in Java nur auf die primitiven Typen angewandt werden kann, die in Ganzzahlen konvertiert werden können (byte, char, short und int). Zum Vergleichen von Strings müssen Sie verschachtelte if-Anweisungen verwenden. Damit sind auch Vergleiche von Strings möglich.



vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Ein Imprint des Markt&Technik Buch- und Software-Verlag GmbH.
Elektronische Fassung des Titels: Java 2 in 21 Tagen, ISBN: 3-8272-5578-3