2016-06-22 2 views
0

Beim Versuch, von einem Lambda zu einem Methodenverweis zu reformieren, habe ich festgestellt, dass es Unterschiede in den Methodenreferenzen gibt, die die lokalen Variablen des Aufrufers nicht erhalten (der lexikalische Umfang?). Wenn ein Lambda als Inline-Code verwendet wird, gibt es überhaupt kein Problem.Java Lambda vs Methodenreferenz - Die lokalen Variablen des Aufrufers werden nicht empfangen

public class MethodRef { 

    public static void main(String[] args) { 
    String appender = "I am appended"; 

    //possible 
    appender("Hello! ", former -> { 
     StringBuilder builder = new StringBuilder(former); 
     builder.append(appender); 
     System.out.println(builder.toString()); 
    }); 

    //not possible 
    appender("Hello! ", this::theRef); 
    } 

    //Delegater 
    public static void appender(String former, Consumer<String> consumer){ 
     consumer.accept(former); 
    } 

    //Method Ref 
    public void theRef(String former){ 
    StringBuilder builder = new StringBuilder(former); 
    builder.append(appender); 
    System.out.println(builder.toString()); 
    } 
} 

Ich verstehe, dass die param Liste der Methode keine „appender“ hat ergeben, aber nicht, dass es eine „versteckte“ param ich verwenden kann, um die lexikalische Vars des Anrufers/Verbraucher Umfang zugreifen?

+0

Sie versuchen, auf eine Member-Methode aus einem statischen Kontext zuzugreifen. Versuchen Sie, 'theRef'-Methodensignatur in' public static void theRef (String former) 'zu ändern und dann' MethodRef :: theRef' anstelle von 'this :: theRef' zu verwenden. Siehe [Verweis auf eine statische Methode] (https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html) in der Oracle-Dokumentation. – Jezor

Antwort

2

Nein, das ist nicht möglich.

Der lexikalische Bereich wird während der Kompilierzeit aufgelöst. Die Methode ist generisch geschrieben und kann von überall technisch aufgerufen werden. Daher kann der Compiler den lexikalischen Umfang aller möglichen Aufrufe nicht erraten.

Wenn Sie eine separate Methode pflegen möchten, müssen Sie den Aufruf nur in das Wrapping von Lambda umbrechen und die lokale Variable als Parameter übergeben. Aber ich nehme an, das war kein ursprüngliches Ziel.

1

Nein, Sie können keine reguläre Methode erstellen, die Zugriff auf lokale Variablen außerhalb der Methode hat.

Der Name von lambdas, die Kopien von lokalen Variablen aus dem Geltungsbereich, in dem es definiert ist, speichert, ist Closure.

Der einzige andere Weg, den ich von der Verwendung von Closures in Java weiß, sind anonyme innere Klassen.

Verwandte Themen