Blockobjekte in Java
Normalerweise ist ein Block ja eine Anweisung.
- normaler Block
{ java.lang.System.out.println( "block" ); }
Syntax
Ein Block kann aber auch als Ausdruck angegeben werden. Bei der Auswertung dieses Ausdrucks ergibt sich der Block als Wert, ohne daß dieser Block dabei auch ausgeführt wird. Der Block wird gewissermaßen nur „zitiert“. Dazu schreibt man eine Objektpfeil »object ->« vor den Block und erhält so einen Ausdruck, dessen Wert ein Objekt ist, welches den Block enthält.
- Blockausdruck (also: ein Block als ein Ausdruck für ein Objekt)
object ->{ java.lang.System.out.println( "block" ); }
- Syntaxdiagramm
Ausdruck
.------.* .--. .-------.
--->( object )--->( -> )--->| block |--->
'------' '--' '-------'* "object" ist kein Schluesselwort
Der Objektpfeil ist praktisch das Gegenstück zum Semikolon der Auswertungsanweisung: Das Semikolon des Auswertungsanweisung macht aus einem Ausdruck eine Anweisung, der Objektpfeil macht aus einer Anweisung einen Ausdruck.
Semantik
Bei der Auswertung eines Blockausdrucks, wie beispielsweise »object ->{ java.lang.System.out.println( "block" ); }«, wird der in dem Blockausdruck enthaltene Block nicht ausgeführt! Vielmehr ergibt die Auswertung eines solchen Blockausdrucks ein Objekt, welches den angegebenen Block enthält. Solch ein Objekt nennen wir auch ein Blockobjekt. Der in einem Blockobjekt enthaltene Block, kann später bei Bedarf einmalig oder auch wiederholt ausgeführt werden.
Man möchte manchmal Blöcke als Argument an eine Methode übergeben, und ein Blockobjekt kann tatsächlich an bestimmte Methoden als Argument übergeben werden. In der nächsten Lektion werden wir einen Blockausdruck beispielsweise als Argument in einem Aufruf einer Methode namens »setOnAction« verwenden.
- Blockausdruck als Argument
setOnAction
(object ->{ java.lang.System.out.println( "block" ); }
)
Bei der Auswertung des Aufrufs »setOnAction( object ->{ java.lang.System.out.println( "block" ); } )« wird der darin enthaltene Block nicht ausgeführt. »object ->{ java.lang.System.out.println( "block" ); }« ist ein Argumentausdruck im Aufruf von »setOnAction«, dessen Wert (das Blockobjekt) an die aufgerufenen Methode übergeben wird.
Die Auswertung des Blockausdruck »object ->{ java.lang.System.out.println( "block" ); }« ergibt ein Blockobjekt, welches den Block »{ java.lang.System.out.println( "block" ); }« enthält; aber bei der Auswertung des Blockausdruck »object ->{ java.lang.System.out.println( "block" ); }« wird der Block »{ java.lang.System.out.println( "block" ); }« nicht ausgeführt.
Die Methode »setOnAction« kann den ihr übergebenen Block dann zunächst erst einmal abspeichern. Die Lebensdauer jenes Blockobjekts ist auf jeden Fall so lange, wie benötigt. Später kann der Block des übergebenen Blockobjektes dann bei Bedarf ausgeführt werden. Dabei ist es möglich, daß er später auch niemals oder wiederholt ausgeführt wird, also niemals, einmal, zweimal, dreimal, und so weiter. Beispiele dazu folgen etwas später in diesem Kurs.
Vergleich mit dem Zitieren von Ausdrücken *
Man kann das Zitieren eines Blocks mit dem Zitieren eines Ausdrucks vergleichen. Auch dabei wird der Ausdruck nicht ausgewertet, sondern als Laufzeitwert behandelt.
Das folgende Programmbeispiel zeigt zunächst die nicht -zitierende Verwendung das Ausdrucks »2 + 3«. Dabei wird der Ausdruck bei seiner Ausgabe ausgewertet und sein Wert ausgegeben – nicht der Ausdruck selber.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( 2 + 3 ); }}transcript
5
Das folgende Programmbeispiel zeigt zunächst die zitierende Verwendung das Ausdrucks »2 + 3«. Dabei wird der Ausdruck bei seiner Ausgabe nicht ausgewertet, sondern wörtlich ausgegeben.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( "2 + 3" ); }}transcript
2 + 3
Um einen Block zu zitieren, wird dieser in dieser Lektion hier jedoch nicht in Anführungszeichen geschrieben, sondern direkt hinter »object ->«. Ein so zitierter Block kann nicht als Argument in »println« verwendet werden, er kann also nicht ausgegeben werden, es gibt aber andere Methoden, die ihn als Argument zu verwenden, wie in der nächsten Lektion gezeigt werden wird.
Hinweis *
Diese Lektion stellt die Programmiersprache Java zunächst vereinfacht dar. In späteren Lektionen sollen einige Details der hier verwendeten Notation noch genauer erklärt werden.
Übungsaufgaben
/ Numerale verdreifachen (Wiederholung aus dem Grundkurs)
Das folgende Programm berechnet das Dreifache des Numerales in einem java.lang.String-Objekt mit der Methode »treble« und gibt das erhaltene Ergebnis aus.
Die Methode »treble« liefert allerdings derzeit nur für den Argumentwert »"3"« das richtige Ergebnis.
Können Sie den Rumpf der Methode »treble« so überarbeiten, daß sie auch für andere Argumentwerte das richtige Ergebnis liefert?
Main.java
public final class Main
{public static java.lang.String treble( final java.lang.String text )
{ return "9"; }public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( treble( "3" )); }}- Protokoll
9