Die Umgebung der Lambda-Ausdrücke

Ein Lambda-Ausdruck „sieht“ seine Umgebung genauso wie der Code, der vor oder nach dem Lambda-Ausdruck steht. Insbesondere hat ein Lambda-Ausdruck vollständigen Zugriff auf alle Eigenschaften der Klasse, genauso wie auch der einschließende äußere Block sie hat. Es gibt keinen besonderen Namensraum (nur neue und vielleicht überdeckte Variablen durch die Parameter), und das ist einer der grundlegenden Unterschiede zwischen Lambda-Ausdrücken und inneren Klassen, bei denen this und super eine etwas andere Bedeutung haben.

Namensräume

Deklariert eine innere anonyme Klasse in der Methode Variablen, so ist der Satz immer „neu“, beziehungsweise die neuen Variablen überschatten vorhandene lokale Variablen aus dem äußeren Kontext. Die Variable compareIgnoreCase kann im Rumpf von compare(…) zum Beispiel problemlos neu deklariert werden:

boolean compareIgnoreCase = true;

Comparator<String> c = new Comparator<String>() {

@Override public int compare( String s1, String s2 ) {

boolean compareIgnoreCase = false; // völlig ok

return …

}

};

In einem Lambda-Ausdruck ist das nicht möglich und folgendes führt zu einer Compilermeldung „variable compareIgnoreCase ist already defined“.

boolean compareIgnoreCase = true;

Comparator<String> c = (s1, s2) -> {

boolean compareIgnoreCase = false; // Compilerfehler

return …

}

this-Referenz

Lambda-Ausdrücke unterscheiden sich von inneren (anonymen) Klassen auch in dem, worauf die this-Referenz verweist: Bei Lambda-Ausdrücke zeigt this auf das Objekt, in dem der Lambda-Ausdruck eingebettet ist, bei inneren Klassen referenziert this die inneren Klasse.

class Application {

Application() {

Runnable run1 = () -> { System.out.println( this.getClass().getName() ); };

Runnable run2 = new Runnable() {

@Override public void run() { System.out.println( this.getClass().getName()); } };

run1.run(); // app.Application

run2.run(); // app.Application$1

}

public static void main( String[] args ) {

new Application();

}

}

Das Programm nutzt this einmal im Lambda-Ausdruck und einmal in der inneren Klasse. Im Fall vom Lambda-Ausdruck bezieht sich ausdrücklich auf das Application-Exemplar, was sich im Klassenamen niederschlägt. Bei der inneren Klasse bekommen wir den Anhang $1, weil es sich um ein anderes Exemplar handelt.

Ähnliche Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert