Ausdrücke
Primäre Ausdrücke
Einfache Ausdrücke
Zusammengesetzte Ausdrücke
Lambda-Ausdrücke
Die Grundbestandteile der Ausdrücke (expressions) sind die primären Ausdrücke.
Bei den primären Ausdrücken handelt es sich um Literale (literals) wie zum Beispiel 12f, 4E−10, 'z', true, '"abc", ..., Methodenaufrufe (method invocations) wie addNumbers(3, 4), doSomething() , ..., new-Anweisungen (object creation expressions and array creation expressions) wie new String(), new Example(), new int[5], new float[3][2], ..., Klassenliterale (class literals) wie float.class, int[].class, Example.class, ..., Zugriffe auf die Werte von Instanz- bzw. Klassenvariablen, von Konstanten und von Array-Komponenten (field accesses and array accesses) wie obj.num, Math.PI, arr[n], ..., Zugriffe auf Objekte wie System.out, myframe.mypanel, ... Zugriffe auf die Werte lokaler Variablen, Methodenreferenzen wie obj::doSomething, Example::new, ..., geklammerte Ausdrücke wie (ch + '.'), (3*x−1), (a < b), (arg1, arg2), ... oder das Schlüsselwort this.
Symbolisieren ω und κ primäre Ausdrücke, die Werte von bestimmtem Typ repräsentieren und stehen die Zeichen # bzw. ¤ für irgendwelche Operatoren, die auf diese Werte angewendet werden bzw. diese Werte miteinander verknüpfen können, dann nennt man #ω, ω# und ω ¤ κ einfach. Einfache Ausdrücke der Form #ω oder ω# heißen unäre Ausdrücke (unary operator expressions); einfache Ausdrücke der Form ω ¤ κ heißen binäre Ausdrücke (binary operator expressions). # ist ein unärer, ¤ ein binärer Operator. Primäre Ausdrücke in einfachen Ausdrücken nennt man Operanden.
Beispiele für unäre Operatoren.
float z = 1.6f;
// Der Wert von z wird um 1 erhöht:
z++;
boolean p = true;
// Der Wert von i wird negiert:
boolean q = !p;
Beispiele für binäre Operatoren.
// Der Wert von PI wird verdoppelt:
double s = 2*Math.PI;
// Es wird eine neue Zeichenkette erzeugt:
String str = "abc" + 'd';
Zusammengesetzte Ausdrücke bestehen aus ineinander verschachtelten oder mit Operatoren verknüpften einfachen Ausdrücken.
Die Auswertung eines Ausdrucks liefert entweder nichts zurück (beim Aufruf einer mit void deklarierten Methode wie im Beispiel 2) oder einen Rückgabewert, dessen Typ durch den Typ der beteiligten Operanden und die Art der verwendeten Operatoren bestimmt wird (wie im Beispiel 1) oder eine Variable (wie im Beispiel 3):
Beispiel 1.
// ein arithmetischer Ausdruck:
(2*x + y) - z;
// Boole'sche Ausdrücke:
!(p && q)||r;
(a <= b)||(b > c);
Beispiel 2.
JLabel label = new JLabel();
label.setFont(new Font("Arial", Font.PLAIN, 16));
Beispiel 3.
int i = 0;
i++;
// i ist hiernach
mit dem Wert 1 belegt.
Vor der Auswertung eines Ausdrucks sind zuweilen Typumwandlungen nötig, die automatisch durchgeführt werden. Beispielsweise liefert die Auswertung des (zulässigen) Ausdrucks
"Die Kreiszahl ist etwa gleich " + 3.14f + '.';
die Zeichenkette "Die Kreiszahl ist etwa gleich 3.14." zurück. Hierfür werden – bevor die Konkatenationsoperatoren „+“ angewendet werden – mittels des float-Wertes 3.14f bzw. des character-Wertes '.' automatisch zwei neue Zeichenketten kreiiert, nämlich "3.14" und ".".
Haben alle die in einem arithmetischen oder einem logischen Ausdruck vorhandenen Operatoren die gleiche Priorität, so wird der jeweilige Ausdruck immer von links nach rechts ausgewertet, das heißt, die entsprechenden Operatoren sind links-assoziativ. Im Übrigen gelten in Java wie in der Mathematik die Regel „Punkt- vor Strichrechnung“ sowie die Klammerregeln. Zuweisungsoperatoren sind rechts-assoziativ, Zuweisungsausdrücke werden also von rechts nach links abgearbeitet. Vergleichsoperatoren sind nicht assoziativ. Also ist beispielsweise der Ausdruck (a > b) > c nicht zulässig. Undefinierte numerische Operationen in einem Programm (etwa Division durch 0) führen bei Verwendung ganzer Zahlen während der Laufzeit zum Abbruch und der Ausgabe einer entsprechenden Fehlermeldung, falls ein solcher Fehler nicht auf geeignete Weise im Programm abgefangen wird.
Ein Lambda-Ausdruck hat die folgende Form:
(Liste) -> Body
Liste ist eine Liste von Parametern, die ggf. auch leer sein kann. Besteht diese Parameterliste nur aus einem einzigen (und nicht typisierten) Parameter, so dürfen die Klammern weggelassen werden. Body ist entweder ein Anweisungsblock, eine einzelne Anweisung oder ein Ausdruck.
Anhand der folgenden Beispiele wird gezeigt, wie Lambda-Ausdrücke verwendet werden können.
Beispiel 1 Sortieren von Zahlen (unter Benutzung der Klassen Arrays und List des Pakets java.util:
List<Integer> list = Arrays.asList(7, 12, 3, -2, 5);
list.forEach(z -> { System.out.print(z + ", "); });
System.out.println();
// liefert die Ausgabe: 7, 12, 3, -2, 5,
list.sort((a, b) -> a.compareTo(b));
list.forEach(z -> { System.out.print(z + ", "); });
// liefert die Ausgabe: -2, 3, 5, 7, 12,
Beispiel 2 Aktivieren eines Buttons (→ Javaprojekt LColoredButtons):
button.addActionListener(e -> doSomething());
Man beachte in den vorstehenden Beispielen, dass innerhalb der Lambda-Ausdrücke Typangaben nicht notwendig waren!