Aufrufe in Java
Einführendes Beispiel
Das folgende Programm gibt eine mehr oder weniger zufällig ausgewählte double-Zahl zwischen 0 (einschließlich) und 1 (ausschließlich) aus.
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.5630878568955987
- Aussprachehinweis
- math random ˈmæθ. ˈræn.dm
»java.lang.Math.random« ist ein Programm, und der Wert des Ausdrucks »java.lang.Math.random()« wird durch jenes Programm festgelegt.
Bei der Auswertung des Ausdrucks »java.lang.Math.random()« wird das Programm »java.lang.Math.random« aus der Java -Standardbibliothek gestartet. Dieses legt für den Ausdruck »java.lang.Math.random()« dann einen Wert zwischen 0 und 1 fest.
Genauer gesagt: Der Wert des Ausdrucks »java.lang.Math.random()« ist ein double-Wert, der bei jeder seiner Auswertungen (bei jeder Programmausführung) zwischen 0 (einschließlich) und ‹ 1−2⁻⁵³ › (also 0,99999999999999988897769753748434595763683319091796875) (einschließlich) liegt; man sagt auch, er liege zwischen 0 (einschließlich) und 1 (ausschließlich). Mehrere Auswertungen ergeben mehr oder weniger zufällige Werte, die gleichmäßig über diesen Bereich verteilt sind, die sogenannten Pseudozufallszahlen.
Das Wichtigste in Kürze Wenn »f« der Name eines Programmes ist, dann ist »f()« ein Ausdruck, und der Wert dieses Ausdrucks wird bei seiner Auswertung durch das Programm »f« festgelegt.
Aufrufausdrücke
Einen Ausdruck, der aus einem Programmnamen und einem direkt folgenden Klammerpaar besteht, nennt man auch einen Aufrufausdruck.
- Java
p()
- auf deutsch (kurz):
- „p -Aufrufausdruck“
- „p -Aufruf“
- „Wert eines Aufrufs von »p«“
- auf deutsch (erklärend):
- „der von der Ausführung des Programmes »p« festgelegte Wert“
Aufrufe
Wenn keine Mißverständnisse möglich sind, bezeichnet man sowohl einen Aufrufausdruck als auch einen Aufrufvorgang einfach als einen Aufruf.
Methoden
Der Name »java.lang.Math.random« steht für ein Programm, welches zur Laufzeit bei der Auswertung des Aufrufsausdrucks »java.lang.Math.random()« gestartet wird.
Solch ein Programm, das von einem anderen Programm aus aufgerufen wird, wird auch als Unterprogramm bezeichnet. Insbesondere in Java nennt man solch ein Unterprogramm eine Methode.
Im Quelltext eines Java -Programms erscheinen nicht die Methoden selber, sondern nur Methodennamen.
Dennoch stellt man sich vor, daß es beim Ablauf des Programms Methoden gibt.
Eine Methode kann man (vorläufig) dadurch definieren, daß sie einen bestimmten Namen hat und am Ende ihrer Ausführung einen Wert liefert.
Als Name im Aufrufausdruck sind nur Namen erlaubt, die auch eine Methode bezeichnen. Solche Namen bezeichnen wir als Methodennamen. Im Aufrufausdruck »java.lang.Math.random()« ist »java.lang.Math.random« beispielsweise der Methodenname.
Methodennamen sind keine Ausdrücke, sie sind keine Wertnamen und keine Felder! Während also beispielsweise »java.lang.Integer.MAX_VALUE« ein Ausdruck ist, ist »java.lang.Math.random« kein Ausdruck. Man kann »java.lang.Math.random« lediglich als einen Namen oder als eine Angabe bezeichnen.
Das folgende Programm zeigt, daß Namen von Methoden bei der Suche nach Feldern nicht berücksichtigt werden.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.random ); }}transcript (übersetzt)
Main.java:4: Fehler: Symbol nicht gefunden
( java.lang.Math.random ); }}
^
Symbol: Variable random
Ort: Klasse Math
1 error
Obwohl Methodennamen keine Felder ihrer Klasse sind, bringt der Name »java.lang.Math.random« doch zum Ausdruck, daß die Methode »random« als ein Bestandteil der Klasse »java.lang.Math« angesehen wird. Wir nennen Felder und Methoden deshalb vereinheitlichend auch Einträge ihrer Klasse.
Die Bedeutung eines Operators ist wie auch die Bedeutung eines Literals bereits durch die Programmiersprache Java (JLS ) definiert, während die Bedeutung der in dieser Lektion neu vorgestellten Methoden, wie »java.lang.Math.random«, durch die Java-SE -API-Dokumentation festgelegt wird.
Das Wichtigste in Kürze (Neufassung) Wenn »m« der Name einer Methode ist, dann ist »m()« ein Ausdruck, und der Wert dieses Ausdrucks wird bei seiner Auswertung durch die Methode »m« festgelegt.
Syntax
Wir führen in dieser Lektion eine neue Art von Ausdruck ein, den Aufrufausdruck . Ein Aufrufausdruck besteht aus einem Namen, dem ein Paar rundern Klammern »(« »)« folgt. Beispielsweise ist »java.lang.Math.random()« ein Aufruf mit dem Namen »java.lang.Math.random« und einem folgenden Paar runder Klammern »()«.
- Syntax eines Aufrufs
Ausdruck
.------. .-. .-.
--->| Name |--->( ( )--->( ) )--->
'------' '-' '-'
Es handelt sich hierbei um mindestens drei lexikalischen Einheiten: die lexikalischen Einheiten des Namens, eine runde Klammer auf »(« und eine runde Klammer zu »)«. Jede runde Klammer eines Aufrufs gilt als eine lexikalische Einheit für sich.
Wenn Java einen Ausdruck erwartet und dann auf einen Namen stößt, kann es zunächst nicht wissen, ob dieser Name bereits ein Postfixausdruck für sich sein soll, oder ob er einen Aufruf einleiten soll. Hier verwendet Java den Zusammenhang: wenn dem Namen ein öffnende Klammer »(« folgt, so wird er als Methodenname angesehen (JLS10, 6.5.1 Syntactic Classification of a Name According to Context). Aus dieser Kontextabhängigkeit ergeben sich einige Details der tatsächlichen Syntaxdiagramme der Sprachspezifikation (JLS10, Kapitel 19), die wir hier etwas vereinfacht haben.
- Neue, erweiterte Syntax (vereinfacht)
Name
.-----------------------.
| .------. .-. v .------------.
---'--->| Name |-->( . )---'--->| Bezeichner |--->
'------' '-' '------------'Aufruf
.-------. .-. .-.
--->| Name |--->( ( )--->( ) )--->
'-------' '-' '-'Primaerausdruck
.-. .----------. .-.
--->.--->( ( )--->| Ausdruck |--->( ) )--->.--->
| '-' '----------' '-' ^
| .----------. |
'------------>| Literal |-------------'
| '----------' |
| .----------. |
'------------>| Aufruf |-------------'
'----------'Postfixausdruck
.-----------------.
--->.--->| Primaerausdruck |---.--->
| '-----------------' ^
| .-----------------. |
'--->| Name |---'
'-----------------'Vorzeichenausdruck
.--------------------.
---.------------>| Postfixausdruck |----.---->
| '--------------------' ^
| .-. .--------------------. |
'--->( - )--->| Vorzeichenausdruck |----'
| '-' '--------------------' |
| .-. .--------------------. |
'--->( + )--->| Vorzeichenausdruck |----'
'-' '--------------------'Multiplikativausdruck
.-----------------------.
---.--->| Vorzeichenausdruck |--------------------------------------.--->
| '-----------------------' ^
| .-----------------------. .-. .--------------------. |
'--->| Multiplikativausdruck |--->( * )--->| Vorzeichenausdruck |---'
| '-----------------------' '-' '--------------------' |
| .-----------------------. .-. .--------------------. |
'--->| Multiplikativausdruck |--->( / )--->| Vorzeichenausdruck |---'
'-----------------------' '-' '--------------------'Additivausdruck
.-----------------------.
---.--->| Multiplikativausdruck |-----------------------------------------.--->
| '-----------------------' ^
| .-----------------------. .-. .-----------------------. |
'--->| Additivausdruck |--->( + )--->| Multiplikativausdruck |---'
| '-----------------------' '-' '-----------------------' |
| .-----------------------. .-. .-----------------------. |
'--->| Additivausdruck |--->( - )--->| Multiplikativausdruck |---'
'-----------------------' '-' '-----------------------'Ausdruck
.-----------------.
--->| Additivausdruck |--->
'-----------------'
Im Falle dieser hier neu vorgestellten Schreibweise nennen wir die runden Klammern auch Aufrufklammern und den damit geschrieben Ausdruck einen Aufrufausdruck.
Man kann die Aufrufklammern aber nicht als einen Operator ansehen, der einem Namen nachgestellt wird, denn ein Operator hat stets Ausdrücke als Operanden, aber ein Name, der aufgerufen wird, ist in diesem Fall kein Ausdruck.
Kontrolle
Wenn ein Programm gerade von einem Rechner ausgeführt wird, so sagt man auch, daß jenes Programm gerade die Kontrolle (über den Rechner) habe, weil der Rechner das tut, was das Programm verlangt.
Das Programm, welches zu einem bestimmten Zeitpunkt die „Kontrolle“ hat, darf den Rechner zu diesem Zeitpunkt benutzen; es läuft also zu diesem Zeitpunkt.
Ein Programm ohne Kontrolle ruht, es ist nicht aktiv.
Übergabe und Rückgabe der Kontrolle
Beim Aufruf eines Programms wird die Kontrolle vom aufrufenden Programm an das aufgerufene Programm übergeben.
Wenn das aufgerufene Programm fertig ist, gibt es die Kontrolle wieder an den Aufrufer zurück.
Rückgabe eines Wertes
Bei der Rückgabe der Kontrolle wird auf der Wert des Aufrufausdrucks festgelegt. Man sagt auch, jener Wert werde von der aufgerufenen Methode zurückgegeben oder geliefert. Der zurückgegebene Wert wird auch als Rückgabewert bezeichnet.
Die Methode »java.lang.Math.random« liefert beispielsweise eine Zufallszahl, sie gibt eine Zufallszahl zurück, ihre Rückgabewert ist eine Zufallszahl.
Klienten
Ein Programm, das eine Methode aufruft oder eine Bibliothek benutzt, wird auch als ein Aufrufer oder Klient jener Methode beziehungsweise Bibliothek bezeichnet. Das Wort „Klient“ bedeutet hier so viel wie „Benutzer“, aber man möchte das Wort „Benutzer“ nur für Menschen verwenden.
Benutzer
Einen Menschen, der ein Programm schreibt, das eine Methode aufruft oder eine Bibliothek benutzt, nennen wir auch einen Benutzer dieser Methode beziehungsweise Bibliothek bezeichnet.
Zuordnung zu Modellen
Hier ordnen wir einige der behandelten Begriffe einem Modell zu.
- Begriffe des Quelltextmodells
- Aufrufausdruck
- Methodenname
- Begriffe des Laufzeitmodells
- Aufrufvorgang
- Methode
Bezüge auf die Zukunft ⃗
Der Ausdruck »java.lang.Math.random()« zeigt, daß es möglich ist, sich in einem Programm mit einem Ausdruck auf einen Wert zu beziehen, der erst in der Zukunft festgelegt und bekannt werden wird. (Der Wert des Aufrufs ist beim Schreiben des Programms noch nicht bekannt, sondern wird erst festgelegt werden, wenn das Programm gestartet werden wird.)
Zusätzliche Regeln ⃗
Als Namen sind in einem Aufruf nicht alle Namen, sondern nur bestimmte Namen erlaubt: Die Namen müssen zu einer Methode gehören, die an anderer Stelle definiert wurde. »java.lang.Math.random« ist beispielsweise ein Name einer Methode aus der Standardbibliothek.
Auswertung ⃗
Die Auswertung eines Aufrufs wie »java.lang.Math.random()« führt zur Ausführung der angegebenen Methode, welche dann den Wert des Aufrufs festlegt.
»java.lang.Math.random()« bedeutet: „Der Wert dieses Ausdrucks soll zum Zeitpunkt der Auswertung dieses Ausdrucks von der Methode »java.lang.Math.random« festgelegt werden.“
Prioritäten *
In der folgenden Liste führen wir den Aufrufoperator zur Übersicht mit auf, obwohl es sich bei den einem Methodennamen nachgestellen Klammmern nicht um einen Operator handelt, da ein Methodenname selber kein Ausdruck (und daher kein Operand) ist. Für die Einordnung in die folgende Tabelle der Operatoren tun wir aber so, als ob der Methodenname ein Ausdruck sei.
- Eigenschaften
S P A (S = Stelligkeit ("Aritaet"), P = Position, A = Assoziativitaet)
() 1 Z Eingeklammerter Ausdruck
() 2 Methodenaufruf
+ - 1 P Unaere vorangestellte Operatoren (Vorzeichen)
* / 2 I L "Punktrechnung": Multiplikation, Division
+ - 2 I L "Strichrechnung": Addition, Subtraktion
Übungsfragen
? Lexikalische Einheiten zählen _
Wie viele lexikalische Einheiten enthält der Aufrufausdruck »java.lang.Math.random()«?
- Syntax eines Aufrufs
Ausdruck
.------. .-. .-.
--->| Name |--->( ( )--->( ) )--->
'------' '-' '-'
? Zusatzfrage *
Welcher Ausdruck hat Zufallszahlen zwischen »0.0« und »1.0« als Wert, wobei die »0.0« ausgeschlossen und die »1.0« eingeschlossen ist?
Klassen *
Manchmal hört man jemanden sagen, daß eine Klasse aufgerufen wird oder aufgerufen werden soll. Man kann aber keine Klassen aufrufen! Nur Methoden können aufgerufen werden. Wenn jemand eine Klasse aufrufen will, sollte daher nachgefragt werden, was er damit meint. Will er vielleicht eine Methode einer Klasse aufrufen?
Vergleich mit dem Zirkumfixoperator »(« »)« *
Die hier neu vorgestellte Schreibweise von Aufrufausdrücken mit Klammern »(« »)« ist nicht mit dem früher eingeführten Zirkumfixoperator »(« »)« zu verwechseln, dessen Klammern wir auch als „Ausdruckklammern“ bezeichnet hatten.
- Syntax des schon früher behandelten Zirkumfixoperators »(« »)«
Ausdruck
.-. .----------. .-.
--->( ( )--->| Ausdruck |--->( ) )--->
'-' '----------' '-'
Die hier neu behandelten Aufrufklammern stehen immer direkt hinter einem Namen, wie beispielsweise in »java.lang.Math.random()« und bilden mit ihm zusammen einen Ausdruck, während die früher behandelten Ausdruckklammern um einen Ausdruck herum geschrieben werden und mit diesem einen neuen Ausdruck, wie beispielsweise »( 65 )«, bilden.
(Wir sagen, daß Klammern leer seien und direkt hinter einen Namen stehen, auch wenn die Klammern noch Leerraum enthalten oder von dem voranstehenden Namen durch Leeraum getrennt sind, da Leerraum hier keine Rolle spielt.)
Übungsaufgaben ⃗
/ Übungsaufgabe ⃗
Schreiben Sie eine Inkarnation der Kategorie »Aufruf« des folgenden Syntaxdiagramms mit dem Namen »java.beans.Beans.isDesignTime«.
- Syntaxdiagramm
Aufruf
.------. .-. .-.
--->| Name |--->( ( )--->( ) )--->
'------' '-' '-'
Die Lösung soll auf einer von Leerzeilen umgebenden Zeile für sich stehen.