Argumente in Java
Einführendes Beispiel
Das folgende Beispiel zeigt die Anwendung des schon behandelten unären Operators »-« auf dem Operandenausdruck »( 3 )«.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( -( 3 )); }}transcript
-3
Im folgenden Programm wurde der Operator »-« durch den Namen »java.lang.Math.negateExact« ersetzt.
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.negateExact( 3 )); }}transcript
-3
- Aussprachehinweis
- negate exact nɪˈgeɪt ɛgˈzækt
Das Ergebnis von »java.lang.Math.negateExact« ist oben dem Ergebnis des Operators »-« gleich. Allerdings sind die runden Klammern um die »3« bei der Verwendung des Namens an Stelle des Operators notwendig (obligatorisch), während sie bei Verwendung des Operators auch hätten entfallen können.
Bei »java.lang.Math.negateExact« handelt es sich ebenfalls um eine Methode, nur sind die Klammern des Aufrufausdrucks diesmal nicht leer (wie bei den bisher behandelten Aufrufausdrücken), sondern enthalten etwas Ähnliches wie einen Operandenausdruck. Der gesamte Aufrufausdruck ist also »java.lang.Math.negateExact( 3 )«.
Der Wert des gesamten Aufrufausdrucks »java.lang.Math.negateExact( 3 )« wird nun durch die Methode »java.lang.Math.negateExact« und den Wert des in die Klammern geschriebenen Ausdrucks »3« gemeinsam bestimmt.
“to negate ” soll hier bedeuten „das Negative einer Zahl herstellen“.
Das Wichtigste in Kürze Wenn »m« der Name einer Methode ist und »x« ein Ausdruck ist, dann ist »m(x)« ein Ausdruck, und der Wert dieses Ausdrucks wird bei seiner Auswertung dann durch die Methode »m« festgelegt, welche dabei den Wert «x» berücksichtigen kann (falls die Methode auf diese Weise aufrufbar ist).
Nicht jede Methode kann mit einem Argumentwert aufgerufen werden – umgekehrt müssen manche Methoden mit einem Argumentwert aufgerufen werden und dürfen nicht ohne Argumentwert aufgerufen werden. Wir werden später sehen, wie man sich über solche Eigenschaften einer Methode informieren kann.
Syntax
Das folgende Syntaxdiagramm erweitert das bisherige Syntaxdiagramm für Aufrufausdrücke um die Möglichkeit eines in die Klammern geschriebenen Ausdrucks.
- Aufrufausdruck (Syntaxdiagramm)
Aufruf
.-------------------.
.-------. .-. | .----------. v .-.
--->| Name |--->( ( )---'--->| Ausdruck |---'--->( ) )--->
'-------' '-' '----------' '-'
Der Argumentausdruck
Ein in die Aufrufklammern geschriebener Ausdruck wird auch Argumentausdruck des Aufrufs oder kurz Argumentausdruck genannt.
Der Argumentausdruck ist – wie jeder Ausdruck – eine Entität des Quelltextmodells.
(Die Aufrufklammern, welche den Argumentausdruck enthalten, werden entsprechend hier auch manchmal als Argumentklammern bezeichnet.)
- Ein Aufrufausdruck
java.lang.Math.negateExact( 3 )
- auf deutsch:
- Aufruf von negate exact mit dem Argument 3
- Wert von negate exact für den Argumentwert 3
- negate exact von 3
Der Argumentwert
Der Wert des Argumentausdruck ist der Argumentwert.
Der Argumentwert ist – wie jeder Wert – eine Entität des Laufzeitmodells.
Wenn es nicht wichtig ist, zwischen dem Argumentausdruck und Argumentwert zu unterscheiden, so spricht am auch einfach nur von einem Argument. Dann muß dem Zusammenhang entnommen werden, ob damit der Argumentausdruck oder der Argumentwert gemeint ist – manchmal sind auch beide Interpretationen gleichzeitig möglich. In diesem Kurs hier ist mit „Argument “ der Argumentausdruck gemeint.
Im Aufrufausdruck »java.lang.Math.negateExact( 2 + 3 )« ist der Argumentausdruck beispielsweise »2 + 3«, während der Argumentwert gleich «5» ist.
Der Argumentwert kann den Wert des gesamten Aufrufs beeinflussen.
Auswertung
Bei der Auswertung eines Aufrufausdrucks mit einem Argument wird zuerst der Argumentausdruck ausgewertet und somit der Argumentwert bestimmt. Alsdann wird die angegebene Methode gestartet. Die laufende Methode kennt den Argumentwert und kann ihn daher berücksichtigen. Die laufende Methode legt dann den Wert für ihren Aufrufausdruck fest.
Eingabe und Ausgabe
Wenn man sich eine Methode als ein Programm vorstellt, dann ist der Argumentwert des Aufrufs eine Eingabe an die Methode und der Wert des Aufrufs die Ausgabe der Methode für diese Eingabe.
„übergeben“ und „zurückgeben“
Man könnte also sagen, daß man einer Methode einen Wert eingibt, woraufhin die Methode dann eine Wert ausgibt. Doch tatsächlich verwendet man hierfür spezielle Begriffe:
Statt: „Der Methode wurde ein Wert eingegeben.“ sagt man: „Der Methode wurde ein Wert übergeben.“.
Statt: „Die Methode hat einen Wert ausgegeben.“ sagt man: „Die Methode hat einen Wert zurückgegeben.“
Auswertung des Ausdrucks »java.lang.Math.negateExact( 2 + 3 )«
Der Argumentausdruck ist »2 + 3«.
Der Argumentwert ist der Wert des Argumentsausdrucks »2 + 3«, der Argumentwert ist also «5».
Der Argumentwert wird an die Methode »java.lang.Math.negateExact« übergeben. (Genauer: Es wird eine Inkarnation der Methode »java.lang.Math.negateExact« mit dem Argumentwert «5» erzeugt und gestartet.)
Schließlich wird von der Methode der Ergebniswert «-5» zurückgegeben. (Genauer: Der Wert wird von der gerade erzeugten Inkarnation zurückgegeben.)
Aussprachehinweis
- Ein Aufrufausdruck
java.lang.Math.floor( java.lang.Math.random() * 4 )
- mögliche Aussprache
- floor von random -Aufruf mal vier (nicht ganz eindeutig)
Aufrufvorgänge ⃗
Unter einem Aufrufvorgang verstehen wir jetzt eine Methodenaktion, also die Auswertung einer bestimmten Methodeninkarnation, also eine Ausführung einer Methode mit bestimmten Argumentwerten. Das heißt, daß es bei der Auswertung des Ausdrucks »java.lang.Math.negateExact( (1+1) * (1+2) )« zunächst einmal der Argumentwert «6» ermittelt wird (dies zählt nicht zum eigentlichen Aufrufvorgang). Dann wird die Methode »java.lang.Math.negateExact« mit dem Argumentwert «6» aufgerufen, also die eigentliche Aktion der Methode veranlaßt, die Ausführung der Inkarnation ›java.lang.Math.negateExact‹ «6». Dieses Aufrufen ist der Aufrufvorgang.
Übungsfragen
? Übergeben und zurückgeben
Welcher Wert wird bei der Auswertung des Ausdrucks »java.lang.Math.negateExact( 2 + 2 )« an die Methode »java.lang.Math.negateExact« übergeben ?
Welcher Wert wird dann von der Methode zurückgegeben ?
? Aufrufe mit Argumentausdrücken lesen
- Aussprachehinweis
- floor ˈflɔɚ
Was ist der Argumentausdruck in dem Aufrufausdruck »java.lang.Math.floor( 2 + 3.2 )«?
Was ist der Argumentwert in dem Aufrufausdruck »java.lang.Math.floor( 2 + 3.2 )«?
? Aufrufe mit Argumentausdrücken lesen (1)
Was ist der Argumentausdruck in dem Aufrufausdruck »java.lang.Math.floor( java.lang.Math.random() * 4 )«?
Welche Werte kann dieser Argumentausdruck haben?
Die Methode »java.lang.Math.floor« ergibt die Abrundung des Wertes ihres Argumentausdrucks zur nächsten darunterliegenden ganzen Zahl (genauergesagt: zur größten ganzen Zahl, die nicht größer als der Argumentwert ist). Beispielsweise sind »java.lang.Math.floor( 5.0 )« und »java.lang.Math.floor( 5.7 )« beide gleich «5.0», während »java.lang.Math.floor( 4.99 )« gleich «4.0» ist.
Welche Werte kann der Aufrufausdruck »java.lang.Math.floor( java.lang.Math.random() * 4 )« haben?
? Zusatzfrage *
Sind alle Werte das Aufrufausdruck »java.lang.Math.floor( java.lang.Math.random() * 4 )« annähernd gleich wahrscheinlich? (Zur Beantwortung dieser Frage kann angenommen werden, daß »java.lang.Math.random()« alle Werte zwischen 0 und 1−2⁻⁵³ [also „fast 1“] mit gleicher Wahrscheinlichkeit liefert.)
? Ermittlung von Operanden ⃗
Kann es eine Funktion »f« geben, die wie in den folgenden Beispielen gezeigt, den linken Operanden ihres Argumentausdrucks ergibt?
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( f( 1 + 3 )); }}transcript
1
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( f( 2 + 2 )); }}transcript
2
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( f( 3 + 1 )); }}transcript
3
Übungsaufgaben ⃗
/ Übungsaufgabe ⃗
Schreiben Sie eine Inkarnation der Kategorie »Aufruf« des folgenden Syntaxdiagramms mit dem Namen »java.lang.Double.hashCode« und dem Ausdruck »22.74 + 1«.
Es soll also für das Kästchen »Name« der Name »java.lang.Double.hashCode« eingesetzt werden, für das Kästchen »Ausdruck« soll der Ausdruck »22.74 + 1« eingesetzt werden.
- Aufrufausdruck (Syntaxdiagramm)
Aufruf
.-------------------.
.------. .-. | .----------. v .-.
--->| Name |--->( ( )---'--->| Ausdruck |---'--->( ) )--->
'------' '-' '----------' '-'
Die Lösung soll auf einer von Leerzeilen umgebenden Zeile für sich stehen.
Kerne und Teilausdrücke ⃗
Wir haben gesehen, daß »-3« und »java.lang.Math.negateExact( 3 )« zwei verschiedene Schreibweise mit gleicher Bedeutung sind. Die Unterscheidung zwischen Operatoren (wie »-«) und Methodennamen (wie »java.lang.Math.negateExact«) ist also eher oberflächlich. Beide stellen den „Kern“ eines Ausdrucks wie »-3« oder »java.lang.Math.negateExact( 3 )« dar: Sie legen also fest, worum es sich eigentlich handelt, nämlich um einen Vorzeichenwechsel. Entsprechend legen wir Oberbegriff für Operatoren und Methodennamen für die Fälle fest, in denen es nicht auf die Schreibweise ankommt.
Definition Ein Kern ist ein Operator oder ein Methodenname.
- Unterbegriffe des Begriffs „Kern“
Kern
|
.-------'-------.
| |Operator Methodenname
Der Kern eines Ausdrucks legt fest, was das für ein Ausdruck ist. So ist »-4« mit dem Kern »-« eine Anwendung des Operators »-« (Kern) und »java.lang.Math.negateExact( 3 )« mit dem Kern »java.lang.Math.negateExact« ein Aufruf der Funktion »java.lang.Math.negateExact« (Kern).
Definition Ein Teilausdruck ist ein Operand oder ein Argument.
- Unterbegriffe des Begriffs „Teilausdruck“
Teilausdruck
|
.-------'-------.
| |Operand Argument
- Beispiel: Zerlegung des Ausdrucks »-3«
- Kern: »-«
- Teilausdruck: »3«
- Beispiel: Zerlegung des Ausdrucks »java.lang.Math.negateExact( 3 )«
- Kern: »java.lang.Math.negateExact«
- Teilausdruck: »3«
Auswertung komplexer AusdrückeAuswertung komplexer Ausdrücke
Aus dem Aufruf »java.lang.Math.negateExact( (1+1) * (1+2) )« wird bei der Auswertung zuerst die Inkarnation ›java.lang.Math.negateExact‹ «6». Die Ausführung der Inkarnation ist dann eine Aktion, und liefert den Wert «-6».
- Die letzten Schritte bei der Auswertung von »java.lang.Math.negateExact( (1+1) * (1+2) )«
(1+1) * (1+2)
| | |
'-------.|.-------'
|||
vvv Herstellung einer Inkarnation des Operators *
2*3
|
v Aktivierung der Inkarnation (Aktion)
6
|
v Herstellung einer Inkarnation der Methode java.lang.Math.negateExact
java.lang.Math.negateExact 6
|
V Aktivierung der Inkarnation (Aktion)
-6
Man kann sich eine Aktion auch als einen Rechenschritt vorstellen. Zu jedem Operator und zu jedem Methodennamen in einem Ausdruck gehört eine Aktion, die während der Auswertung des Ausdrucks stattfindet.
Keine Übergabe des Argumentausdrucks ⃗
Daß eine Methode nur den Argumentwert, aber nicht den Argumentausdruck erfährt, heißt beispielsweise, daß es unmöglich ist, eine Methode ›left‹ zu schreiben, die man mit »left( 2 + 3 )« aufrufen kann, um den linken Operanden der Summe (»2«) zu erhalten. Die Methode ›left‹ erfährt nur den Argumentwert (also «5») und kann daher nicht wissen, was der linke Operand der Summe ist.
Aus dem Aufruf »java.lang.Math.negateExact( (1+1) * (1+2) )« wird bei der Auswertung zuerst die Inkarnation ›java.lang.Math.negateExact‹ «6». Die Ausführung der Inkarnation ist dann eine Aktion, und liefert den Wert «-6».
- Die letzten Schritte bei der Auswertung von »java.lang.Math.negateExact( (1+1) * (1+2) )«
(1+1) * (1+2)
| | |
'-------.|.-------'
|||
vvv Herstellung einer Inkarnation des Operators *
2*3
|
v Aktivierung der Inkarnation (Aktion)
6
|
v Herstellung einer Inkarnation der Methode java.lang.Math.negateExact
java.lang.Math.negateExact 6
|
V Aktivierung der Inkarnation (Aktion)
-6
Man kann sich eine Aktion auch als einen Rechenschritt vorstellen. Zu jedem Operator und zu jedem Methodennamen in einem Ausdruck gehört eine Aktion, die während der Auswertung des Ausdrucks stattfindet.
Keine Übergabe des Argumentausdrucks ⃗
Daß eine Methode nur den Argumentwert, aber nicht den Argumentausdruck erfährt, heißt beispielsweise, daß es unmöglich ist, eine Methode ›left‹ zu schreiben, die man mit »left( 2 + 3 )« aufrufen kann, um den linken Operanden der Summe (»2«) zu erhalten. Die Methode ›left‹ erfährt nur den Argumentwert (also «5») und kann daher nicht wissen, was der linke Operand der Summe ist.