Aufrufausdrücke in Operatorausdrücken in Java
Operanden dürfen auch Aufrufe sein.
Ein Aufruf einer Methode, der den Typ »double« hat darf überall dort verwendet werden, wo wir bisher auch ein double-Literal oder einen double-Operatorausdruck mit dem Typ »double« verwendet haben. Der Aufrufausdruck steht dabei für seinen Wert, also den Rückgabewert der aufgerufenen Methode.
Wir haben bisher schon Literale als Ausdrücke kennengelernt.
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
1
Wir haben schon Ausdruckklammern als Operatoren kennengelernt.
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
1
Zuletzt hatten wir Methodenaufrufe als Ausdrücke kennengelernt.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.random() ); }}java.lang.System.out
0.649382788155440
Das folgende Beispiel zeigt nun, daß Aufrufe auch als Operanden von Operatoren verwendet werden können. Im folgenden Beispiel ist der Aufruf »java.lang.Math.random()« Operand des Klammeroperators.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( ( java.lang.Math.random() )); }}java.lang.System.out
0.440784869382155
Wir hatten zuvor schon gesehen, daß Literale und andere Operatorausdrücke Operanden sein können. Überall, wo ein Literal stehen kann, kann stattdessen auch ein Aufruf mit demselben Datentyp, wie ihn das Literal hat, stehen. Daher können auch Aufrufe als Operanden verwendet werden. Allgemein sind als Operanden alle Ausdrücke mit einem passenden Datentyp zulässig.
Das folgende Beispiel zeigt eine doppelte Anwendung des Klammeroperators auf einen Aufruf (die hier keine tieferen Sinn hat, sondern nur als ein weiteres Beispiel dienen soll).
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( ( ( java.lang.Math.random() ))); }}java.lang.System.out
0.440784869382155
Das folgende Beispiel zeigt eine Division mit zwei Operanden: der erste Operand ist ein Methodenaufruf, der zweite ein Numerale.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.random()/10. ); }}java.lang.System.out
0.07826832232991582
Das folgende Beispiel zeigt eine Summe mit zwei Operanden: der erste Operand ist ein Methodenaufruf, der zweite ein Numerale.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.random() + 10 ); }}java.lang.System.out
10.7895131299083
Das folgende Beispiel zeigt eine Produkt mit zwei Operanden: der erste Operand ist ein Numerale, der zweite ein Methodenaufruf.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( 100 * java.lang.Math.random() ); }}java.lang.System.out
60.902988830645825
Schritte bei der Auswertung von »java.lang.Math.random() + 10«
Bei der Auswertung des Ausdrucks »java.lang.Math.random() + 10« werden die folgenden Schritte ausgeführt:
- Die Methode »java.lang.Math.random« wird gestartet und unser Programm (das Hauptprogramm) wartet das Ende ihrer Ausführung ab.
- Die »java.lang.Math.random« gibt eine Zufallszahl zurück. Wir nehmen hier als Beispiel an, die Zufallszahl sei »0.5«.
- Nun ist die Ausführung der aufgerufenen Methode beendet und unser Programm kann weiterlaufen.
- Der Operator »+« wird als „0.5+10“ inkarniert. Die Inkarnation wird ausgeführt und ergibt »10.5«.
- Der Wert des gesamten Ausdrucks »java.lang.Math.random() + 10« wird als die im vorigen Schritt erhaltene »10.5« festgelegt.
Unbedingte Auswertung
Alle Stellen der bisher behandelten Operatoren sind strikt, das heißt, daß Operanden bei der Auswertung einer Anwendung eines Operators alle ausgewertet werden (selbst, wenn ihr Wert gar nicht benötigt werden sollte.)
Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( 0.0 * java.lang.Math.random() ); }}Protokoll
0.0
Obwohl bei »0.0 * …« das Ergebnis immer »0.0« ist, wird »java.lang.Math.random()« trotzdem ausgewertet!
Übungsfragen
? Typen und Wertebereiche
Welchen Typ hat der Ausdruck »( ( java.lang.Math.random() ))«?
In welchem Bereich liegt der Wert des Ausdrucks »( ( java.lang.Math.random() ))«?
Welchen Typ hat der Ausdruck »java.lang.Math.random() + 10«?
In welchem Bereich liegt der Wert des Ausdrucks »java.lang.Math.random() + 10«?
In welchem Bereich liegt der Wert des Ausdrucks »10 * java.lang.Math.random()«?
In welchem Bereich liegen die Vorkommastellen der Werte des Ausdrucks »3 * java.lang.Math.random()«?
In welchem Bereich liegt der Wert des Ausdrucks »10 * java.lang.Math.random() + 10«?
Kommentar Diese Übungsfragen zeigen, wie verschiedene Elemente der Programmiersprache (»*«, »+« und »java.lang.Math.random()«) kombiniert werden können, um ein bestimmtes Ergebnis, nämlich einen bestimmten Wertebereich, zu erhalten. Wenn man einmal die einzelnen Elemente einer Programmiersprache kennengelernt hat, so ist dieses Kombinieren das eigentliche Programmieren. In einigen kurzen Kursen ist leider zu wenig Zeit für das Üben dieser Fähigkeit zum Kombinieren der Sprachelemente. Wenn man anfängt, Programmieren zu lernen, könnte man denken, das Erlernen des Programmierens bestehe im Erlernen der einzelnen Sprachelemente der Programmiersprache; tatsächlich fängt das Erlernen des Programmierens aber erst danach an!
Anmerkung Diese Übungsfragen gehören zum roten Faden „Würfeln“.