Hinter einem Kontextausdruck mögliche Verbaufrufe in Java
Mit „Kontextausdruck “ ist hier ein Ausdruck gemeint, der als Kontext verwendet wird, wie etwa »""« in »"".valueOf( 3 )«.
Erinnerung an Aufrufe mit Referenztypnamen als Kontext
Wir erinnern zunächst an die schon im Grundkurs behandelte Situation mit einem Referenztypnamen als Kontext.
ℛ statisches Aufrufprinzip Ein Typname als Kontext erlaubt einen Verbaufruf, wenn es eine statische Methode in dem durch den Typnamen benannten Typ gibt, die zu jenem Verbaufruf paßt.
(Dieses statische Aufrufprinzip ist etwas vereinfacht, da es beispielsweise nicht die Situation berücksichtigt, in der es bei Überladung mehrere gleich gut passende Methode zu einem Aufruf gibt, und der Aufruf deswegen nicht akzeptiert werden kann.)
Ein Referenztypname als Kontext erlaubt einen nachgestellten Verbaufruf dann, wenn es eine statische Methode in dem Referenztyp gibt, die zu dem Aufruf paßt. Ob es eine solche statische Methode gibt, kann man in der Dokumentation des Referenztyps nachlesen.
In den beiden folgenden Beispielen ist »java.lang.Math« ein Referenztypname, und »random()« sowie »random( 2 )« sind Verbaufrufe. »java.lang.Math« ist kein Ausdruck.
Im direkt folgenden Beispiel ist der Aufruf erlaubt, da der Referenztyp »java.lang.Math« laut Dokumentation eine statische Methode »random()« enthält.
- Der Kontext enthält eine zum Aufruf passende Methode
java.lang.Math.random()
Im direkt folgenden Beispiel ist der Aufruf nicht erlaubt, da der Referenztyp »java.lang.Math« laut Dokumentation keine statische random-Methode enthält, welche die Argumentliste »2« akzeptiert.
- Der Kontexts enthält keine zum Aufruf passende Methode
java.lang.Math.random( 2 )
Aufrufe mit einem Ausdruck als Kontext
ℛ nicht-statisches Aufrufprinzip Ein Ausdruck als Kontext erlaubt einen Verbaufruf, wenn der Typ jenes Ausdrucks ein Referenztyp ist und es in jenem Referenztyp eine zum Verbaufruf passende Methode gibt.
In den beiden folgenden Beispielen ist »java.lang.System.out« ein Ausdruck. Der Typ von »java.lang.System.out« ist »java.io.PrintStream«. »print( 2 )« sowie »print()« sind Verbaufrufe.
Im folgenden Beispiel ist der Aufruf erlaubt, da der Referenztyp »java.io.PrintStream« laut Dokumentation print-Methode enthält, welche die Argumentliste »2« akzeptiert.
- Der Typ des Kontexts enthält eine zum Aufruf passende Methode
java.lang.System.out.print( 2 )
Im folgenden Beispiel ist der Aufruf erlaubt, da der Referenztyp »java.io.PrintStream« laut Dokumentation print-Methode enthält, welche die Argumentliste »2« akzeptiert.
- Der Typ des Kontexts enthält keine zum Aufruf passende Methode
java.lang.System.out.print()
Kontexte enthalten Methoden
Wir sagen zur Vereinfachung auch bei nicht-statischen Aufrufen einfach, daß der Kontext ein passende Methode enthalte. Beim Aufruf »java.lang.System.out.print( 2 )« stellen wir uns also vor, daß dieser möglich ist, weil der Ausdruck »java.lang.System.out« eine Methode »print(int)« enthält. – Genau genommen müßte man dazu ja eigentlich sagen, daß der Typ des Ausdrucks und nicht der Ausdruck selber solch eine Methode enthalte.
Wir stellen uns also vor, daß der Ausdruck »java.lang.System.out« verschiedene Methoden, wie »print(int)«, »print(double)«, »println()« und so weiter enthält, und wir eine davon aufrufen können, indem wir einen Punkt ».« und einen passenden Verbaufruf hinter diesen Ausdruck schreiben.
Kontexte enthalten Methoden. Deswegen können wir Methoden eines Kontexts aufrufen.
Hinweis für den Dozenten ► N: Die in einem Ausdruck enthaltenen Aufrufe
Übungsfragen
? Typ
Welchen Typ haben die folgenden Ausdrücke jeweils?
- »java.lang.System.out«
- »java.lang.System.in«
? Art des Kontexts
Ist der Kontext der folgenden Aufrufe jeweils statisch oder nicht-statisch?
(Typnamen sind statische Kontexte, Ausdrücke sind nicht-statische Kontexte.)
- »java.lang.Integer.TYPE.getName()«
- »java.lang.Thread.currentThread()«
? Typ des Kontexts
Um die Dokumentation einer in einem Aufruf verwendeten Methode nachlesen und damit den Aufruf verstehen zu können, ist es wichtig, den Typ des Kontexts des Aufrufs zu kennen.
Welchen Typ hat der Kontext der folgenden Aufrufe?
- »java.io.File.separator.charAt( 0 )«
- »java.util.function.IntUnaryOperator.identity().applyAsInt( 8 )«
? Typ des Kontexts (1) *
Warum ist die folgende Aussage schlecht formuliert?
- Der Kontext des Aufrufs »java.lang.Thread.currentThread()« hat den Typ »java.lang.Thread«.
Symbole *
Die Signatur eines Aufrufs (Aufrufsignatur) ist der einfache Aufruf, in dem jedes Argument durch seinen Typ ersetzt wurde. So erhält man beispielsweise aus »java.lang.System.out.print1n( 2 )« die Aufrufsignatur »print1n(int)«. Der Compiler erwartet, im Typ des Kontexts eines nicht-statischen Aufrufs eine zur Aufrufsignatur passende Methode zu finden.
Der Compiler nennt eine Aufrufsignatur in einigen Fehlermeldungen auch ein Symbol.
Main.java:35: error: cannot find symbol
{ java.lang.System.out.print1n( 2 ); }}
^
symbol: method print1n(int)
location: variable out of type PrintStream
1 erro
Auch hier sieht man wieder, daß der Compiler auch den Typ des Kontexts (»PrintStream«) anzeigt.