Der Block als Anweisung in Java
Bisher kennen wir zwei Arten von Anweisungen:
- Ausgabeanweisungen (mit »print«) und
- Aufrufanweisungen (= Aufruf + Semikolon »;«).
In dieser Lektion wird nun ein weiterer Typ von Anweisung vorgestellt werden.
Einführende Beispiele
Im folgenden Beispielprogramm findet sich ein Block.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( 7 ); }} /*
*
'-------------- Block ---------------' */java.lang.System.out
7
Der Block ist derjenige Teil des obenstehenden Programms, welcher aus den inneren geschweiften Klammern samt ihrem Inhalt besteht.
- Ein Block
{ java.lang.System.out.println( 7 ); }
Ein Block mit mehreren Anweisungen
Ein Block kann auch mehrere Anweisungen enthalten, die dann direkt hintereinandergeschrieben werden. Das folgenden Programm zeigt einen Block mit zwei Anweisungen. (Dies wurde im Kurs schon früher gesagt und wird hier noch einmal wiederholt.)
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( 7 );
java.lang.System.out.println( 9 ); }}java.lang.System.out
7
9
Solche Programme mit mehreren Anweisungen haben wir schon geschrieben. In dieser Lektion hier werden nun noch einige weitere Aspekte von Blöcken beleuchtet. Insbesondere wird in dieser Lektion hervorgehoben, daß ein Block selber auch eine Anweisung ist.
Syntax
Ein Block ist eine Anweisung.
Ein Block besteht aus einer geschweiften Klammer auf »{«, einer optionalen Folge von Anweisungen, und einer geschweiften Klammer zu »}«.
- Block (Syntaxdiagramm)
Anweisung
.-. .-.
---->( { )----.----------------------.---->( } )---->
'-' | | '-'
| .-----------. |
'----| Anweisung |<----'
'-----------'
Jede der beiden geschweiften Klammer ist eine lexikalische Einheit für sich. (Eine geschweifte Klammer verlangt niemals Leeraum vor oder hinter sich, da sie nie mit anderen Zeichen zu einer längeren lexikalischen Einheit verschmelzen kann.)
Ausführung
Bei der Ausführung eines Blocks werden die im Block enthaltenen Anweisungen in der Reihenfolge, in der sie im Quelltext stehen, von der ersten bis zur letzten zeitlich hintereinander ausgeführt. Dabei wird mit der Abarbeitung einer im Block enthaltenen Anweisung erst begonnen, wenn die Abarbeitung der vorigen Anweisung beendet wurde.
Man kann sagen, daß bei der Ausführung eines Blocks, die räumliche Reihenfolge der im Quelltext in ihm enthaltenen Anweisungen in eine zeitliche Reihenfolge der Ausführungen der enthaltenen Anweisungen übersetzt wird.
Die Ausführung eines Programms
Bei der Ausführung eines Programms wird immer der Block hinter »public static void main( final java.lang.String[] args )« ausgeführt.
Wir betrachten beispielsweise das folgende Programm.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( 9 + java.lang.Math.random() );
java.lang.Thread.dumpStack(); }}transcript
9.826949831983175
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1329)
at Main.main(Main.java:4)- Aussprachehinweis
- thread θrɛd
Bei der Ausführung des obenstehenden Programms der folgende Block ausgeführt.
- Block
{ java.lang.System.out.println( 9 + java.lang.Math.random() );
java.lang.Thread.dumpStack(); }
Bei der Ausführung des obigen Blocks wird zuerst die erste Anweisung ausgeführt. Es handelt sich um eine Ausgabeanweisung. Diese wertet zunächst den Ausdruck »9 + java.lang.Math.random()«. Dabei wird zuerst der Operand »9« und dann der Operand »java.lang.Math.random()« ausgewertet, die erhaltenen Werte werden alsdann summiert. Die Ausgabeanweisung gibt dann eine Textdarstellung des erhaltenen Summenwertes aus.
Danach wird die zweite Anweisung ausgeführt. Es handelt sich um eine Aufrufanweisung. Daher wird ihr Ausdruck »java.lang.Thread.dumpStack()« ausgewertet, was zur Ausgabe eines Stapelberichtes führt.
Der Block als eine einzige Anweisung ⃗
Ein Block kann zwar mehrere Anweisungen enthalten, aber er verbindet diese zu einer einzigen Anweisung. Daher wird ein Block manchmal auch Verbundanweisung genannt. Dies bedeutet, daß ein Block an Stellen in Programm verwendet werden darf, an denen nur eine einzige Anweisung gestattet ist, selbst wenn er seinerseits intern mehrere Anweisungen enthält. (Dies kann man damit vergleichen, daß ein Paket auch dann als nur ein Paket gezählt wird, wenn es intern mehrere Pakete enthält.)
Die Verschachtelung von Blöcken
Da ein Block selber auch eine Anweisung ist, darf ein Block auch in einen anderen Block eingesetzt werden!
In dem folgenden Programm dient der innerste Block beispielsweise dazu, klarzustellen, auf welche Zeilen sich der Kommentar bezieht.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ { /* Ausgabe einiger gerader Zahlen */
java.lang.System.out.println( 4 );
java.lang.System.out.println( 12 );
java.lang.System.out.println( 8 ); }
java.lang.System.out.println( 7 );
java.lang.System.out.println( 17 );
java.lang.System.out.println( 11 );
java.lang.System.out.println( 9 ); }}java.lang.System.out
4
12
8
7
17
11
9
Die Augabe des Programms würde sich aber nicht ändern, wenn die inneren Blockklammern entfernt werden würden.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ /* Ausgabe einiger gerader Zahlen */
java.lang.System.out.println( 4 );
java.lang.System.out.println( 12 );
java.lang.System.out.println( 8 );
java.lang.System.out.println( 7 );
java.lang.System.out.println( 17 );
java.lang.System.out.println( 11 );
java.lang.System.out.println( 9 ); }}java.lang.System.out
4
12
8
7
17
11
9
Strukturierung mit Blöcken
Das folgenden Programm gibt ein Lied aus.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( "Auf einem Baum ein Kuckuck, -" );
java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" );
java.lang.System.out.println( "Auf einem Baum ein Kuckuck sass." );
java.lang.System.out.println( "Da kam ein junger Jaeger, -" );
java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" );
java.lang.System.out.println( "Da kam ein junger Jaegersmann." );
java.lang.System.out.println( "Der schoss den armen Kuckuck, -" );
java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" );
java.lang.System.out.println( "Der schoss den armen Kuckuck tot." ); }}transcript
Auf einem Baum ein Kuckuck, -
Sim sa la dim, bam ba,
Sa la du, sa la dim -
Auf einem Baum ein Kuckuck sass.
Da kam ein junger Jaeger, -
Sim sa la dim, bam ba,
Sa la du, sa la dim -
Da kam ein junger Jaegersmann.
Der schoss den armen Kuckuck, -
Sim sa la dim, bam ba,
Sa la du, sa la dim -
Der schoss den armen Kuckuck tot.
In dem folgenden Beispielprogramm werden Blöcke (und zwei Leerzeilen) zur übersichtlichen Gliederung von Anweisungen zur Ausgabe eines Liedtextes verwendet. Die Klammern schließen jeweils eine Strophen und den Kehrreim ein.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{{ java.lang.System.out.println( "Auf einem Baum ein Kuckuck, -" );
{ java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" ); }
java.lang.System.out.println( "Auf einem Baum ein Kuckuck sass." ); }{ java.lang.System.out.println( "Da kam ein junger Jaeger, -" );
{ java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" ); }
java.lang.System.out.println( "Da kam ein junger Jaegersmann." ); }{ java.lang.System.out.println( "Der schoss den armen Kuckuck, -" );
{ java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" ); }
java.lang.System.out.println( "Der schoss den armen Kuckuck tot." ); }}}transcript
Auf einem Baum ein Kuckuck, -
Sim sa la dim, bam ba,
Sa la du, sa la dim -
Auf einem Baum ein Kuckuck sass.
Da kam ein junger Jaeger, -
Sim sa la dim, bam ba,
Sa la du, sa la dim -
Da kam ein junger Jaegersmann.
Der schoss den armen Kuckuck, -
Sim sa la dim, bam ba,
Sa la du, sa la dim -
Der schoss den armen Kuckuck tot.
Die Klammer am Anfang einer jeden Strophe wirkt optisch wie ein Gliederungspunkt, der es erlaubt, am linken Textrand den Anfang einer Strophe schnell zu finden.
Der leere Block
Der Block kann beliebig viele Anweisungen enthalten, also auch gar keine (null).
Die Ausführung eines solchen leeren Blocks hat keine Wirkung. Man kann dies mit der leeren Zeichenfolge »""« vergleichen, die kein Zeichen enthält.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.print( "Hallo, W" );
{} {} {} {} {} {} {} {} {} {} {} {} {} {}
java.lang.System.out.println( "elt" ); }}transcript
Hallo, Welt
Der leere Block ist die kürzeste uns bisher bekannte Anweisung.
Anweisungen (Zusammenfassung)
Wir kennen jetzt folgende Arten von Anweisungen:
- die Ausgabeanweisungen,
- die Aufrufanweisung und
- den Block.
- Anweisung
Anweisung
.------------------.
----.--->| Ausgabeanweisung |----.--->
| '------------------' |
| .------------------. |
'--->| Aufrufanweisung |----'
| '------------------' |
| .------------------. |
'--->| Block |----'
'------------------'
Übungsfragen
? Ausgabe vorhersagen
Welche Ausgabe erzeugt das folgende Programm?
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.print( "a" );
{ java.lang.System.out.print( "b" );
java.lang.System.out.print( "c" ); }
java.lang.System.out.println( "d" ); }}
? Anweisungen *
Sind die vorletzte und vorvorletzte Zeile des folgenden Programms zusammen ein syntaktisch korrekter Block?
Falls die Antwort auf die voranstehende Frage „Ja“ lautet, sind noch zwei weitere Fragen zu beantworten:
- Wie viele Anweisungen finden sich in dem Programm?
- Wie viele Zeilen hat das Programm?
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.Math.random(); java.lang.Math.cos( 0 ); java.lang.Math.cos( 0 ); {} {} {}
java.lang.System.out.println( 22 ); java.lang.System.out.println( 21 ); }
}
Übungsaufgaben *
/ Editieren der Lied-Klasse *
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{
{ java.lang.System.out.println( "Auf einem Baum ein Kuckuck, -" );
{ java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" ); }
java.lang.System.out.println( "Auf einem Baum ein Kuckuck sass." ); }
{ java.lang.System.out.println( "Da kam ein junger Jaeger, -" );
{ java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" ); }
java.lang.System.out.println( "Da kam ein junger Jaegersmann." ); }
{ java.lang.System.out.println( "Der schoss den armen Kuckuck, -" );
{ java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" ); }
java.lang.System.out.println( "Der schoss den armen Kuckuck tot." ); }}}
Überarbeiten Sie den über diesem Satz stehenden Quelltext:
- vertauschen Sie die erste und die letzte Strophe,
- entfernen Sie den Kehrreim aus der mittleren Strophe und
- entfernen Sie das Komma hinter jedem »du«.
Falls Sie die Positionierung der geschweiften Klammern als unübersichtlich empfinden, so können Sie diese vor dem Editieren auch erst einmal umstellen, beispielsweise wie folgt.
Es gibt unterschiedliche Ansichten darüber, welche Positionierung der Klammern am übersichtlichsten ist. Die folgende Art der Formatierung hebt die geschweiften Klammern deutlich hervor, indem jede Klammer auf eine Zeile für sich steht. Sie wird in diesem Kurs aber nicht ständig verwendet, weil sie in der Höhe viel Platz kostet und dadurch das Erfassen des gesamten Programms erschwert.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{
{java.lang.System.out.println( "Auf einem Baum ein Kuckuck, -" );
{
java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" );}
java.lang.System.out.println( "Auf einem Baum ein Kuckuck sass." );
}
{java.lang.System.out.println( "Da kam ein junger Jaeger, -" );
{
java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" );}
java.lang.System.out.println( "Da kam ein junger Jaegersmann." );
}
{java.lang.System.out.println( "Der schoss den armen Kuckuck, -" );
{
java.lang.System.out.println( "Sim sa la dim, bam ba," );
java.lang.System.out.println( "Sa la du, sa la dim -" );}
java.lang.System.out.println( "Der schoss den armen Kuckuck tot." );
}
}
}
Zitate aus der JLS *
“A block is a sequence of statements … within braces.” – JLS7, 14.2
“A block is executed by executing each of the local variable declaration statements and other statements in order from first to last (left to right).” – JLS7, 14.2
“Statement:
StatementWithoutTrailingSubstatement
…
StatementWithoutTrailingSubstatement:
Block ” – JLS8, 14.5 Statements
Struktogramm für einen Block *
Ein Struktogramm ist eine graphische Darstellung eines Blocks. Ein Kästchen in einem Block steht für eine Anweisung
In die Kästchen eines Struktogramms kann Pseudocode oder Quelltext geschrieben werden.
- Struktogramm für den vorangegangenen Block
.---------------------------------.
| Ausgabe 7 |
|---------------------------------|
| Ausgabe 9 |
'---------------------------------'
Die Positionierung von Klammern *
Die folgenden beiden Programme zeigen zwei verschiedenen Möglichkeiten zur Positionierung geschweifter Klammern. (Weitere Möglichkeiten sind denkbar.)
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( 1 );
{ java.lang.System.out.println( 2 ); }
java.lang.System.out.println( 3 ); }}java.lang.System.out
1
2
3Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( 1 );{
java.lang.System.out.println( 2 );
}java.lang.System.out.println( 3 ); }}
java.lang.System.out
1
2
3
Ein Leser dieses Kurses braucht die in diesem Kurs oft verwendete Art der Positionierung geschweifter Klammern nicht zu übernehmen, sondern kann die geschweiften Klammern beim Schreiben eigener Programme so positionieren, wie dies für ihn am übersichtlichsten ist.
Falls ein Leser dieses Kurses im Rahmen einer Ausbildung, einer Prüfung, eines Programmierprojekts oder eines Arbeitsverhältnisses Programme schreibt, sollte er dort erfragen, welcher Stil dort verlangt wird oder üblich ist, und dann diesen Stil verwenden.
Anweisungen und Semikolons *
Oft hört man die falsche Aussage „Jede Anweisung endet mit einem Semikolon.“
Wir kennen aber nun schon den Block, der auch eine Anweisung ist, als ein Gegenbeispiel: Ein Block endet mit einer geschweiften Klammer!
Richtig wäre es höchstens zu sagen: „Jede Ausgabe- oder Aufrufanweisung endet mit einem Semikolon.“
Blöcke und Blockanweisungen *
Der Block sollte nicht als „Blockanweisung“ bezeichnet werden, obwohl er eine Anweisung ist, da das Wort „Blockanweisung“ (englisch “block statement”) in manchen Java -Texten schon wieder eine andere Bedeutung hat.
Vergleich mit Zeichenfolgenliteralen *
Wir können die Syntax eines Blocks mit der Syntax eines Zeichenfolgenliterals vergleichen.
- Block (Syntaxdiagramm)
Anweisung
.-. .-.
--->( { )---.--------------------.--->( } )--->
'-' ^ | '-'
| .-----------. |
'---| Anweisung |<---'
'-----------'- Morphologisches Diagramm
Zeichenfolgenliteral (vereinfacht)
.-. .-.
|-|--->( " )---.--------------------.--->( " )--->|-|
'-' ^ | '-'
| .-----------. |
'---| Zeichen |<---'
'-----------'
Man sieht, daß der Aufbau eines Blocks dieselbe Struktur wie der Aufbau eines Zeichenfolgenliterals hat.