2016-02-25 4 views
9

Wenn Lambda-Ausdruck verwendet wird, erstellt Java eine anonyme (nicht statische) Klasse. Nicht statische innere Klassen enthalten immer Referenzen auf ihre umschließenden Objekte.Gibt es eine Möglichkeit für Java-Lambda-Ausdruck, keine Referenz auf ein umschließendes Objekt zu haben?

Wenn dieser Lambda-Ausdruck aus einer anderen Bibliothek aufgerufen wird, die Lambda in einem anderen Prozess aufrufen kann, stürzt der Aufruf mit der Ausnahme Klasse nicht gefunden ab, weil die Klasse des umschließenden Objekts in einem anderen Prozess nicht gefunden werden kann.

Betrachten Sie dieses Beispiel:

public class MyClass { 
    public void doSomething() { 
     remoteLambdaExecutor.executeLambda(value -> value.equals("test")); 
    } 
} 

Java wird eine anonyme innere Klasse, die bestimmte funktionelle Schnittstelle implementiert und es als Parameter an executeLambda() übergeben. Dann nimmt remoteLambdaExecutor diese anonyme Klasse über den gesamten Prozess zur Remote-Ausführung. Remote-Prozess weiß nichts über MyClass und werfen

java.lang.ClassNotFoundException: MyClass 

Weil es MyClass für das einschließende Objekt Referenz benötigt.

Ich kann immer eine statische Implementierung der funktionalen Schnittstelle verwenden, die von einer API erwartet wird, aber das verhindert den Zweck und verwendet keine Lambda-Funktionalität.

Gibt es eine Möglichkeit, es mit Lambda-Ausdrücken zu lösen?

UPDATE: Ich kann auch keine statische Klasse verwenden, es sei denn, sie wird irgendwie in diesen anderen Prozess exportiert.

+0

'kann Lambda in einem anderen Prozess aufrufen': klingt wie ein Chiasmus – wero

+0

Vielleicht ist Java die falsche Sprache dafür. Vielleicht brauchen Sie eine Skriptsprache. –

Antwort

6

Ihre ursprüngliche Prämisse ist falsch. Die JRE wird nicht eine anonyme innere Klasse generieren. Es kann zwar eine Klasse generieren, aber wenn Ihr Lambda-Ausdruck nicht auf this oder ein nicht-static Mitglied der Klasse zugreift, wird nicht einen Verweis auf die this Instanz behalten.

Dies bedeutet jedoch nicht, dass die Klasse selbst unnötig ist. Da die Klasse den Code des Lambda-Ausdrucks hostet, wird es immer benötigt. In dieser Hinsicht ändert Ihre Lösung, eine verschachtelte Klasse static zu verwenden, nichts daran, da dann die verschachtelte Klasse static für die Ausführung des Codes benötigt wird.

Es gibt keine Möglichkeit, ein Objekt an eine Remote-Ausführungseinrichtung zu übertragen, ohne die Klasse zu übertragen, die den auszuführenden Code enthält (es sei denn, die Klasse ist bereits am Remote-Standort vorhanden).

+1

Mit anderen Worten, ein Java-Lambda ähnelt eher einem C++ - Funktionszeiger als einem Lisp-Lambda. Das Java-Lambda sagt Ihnen, welcher Code ausgeführt werden soll, enthält diesen Code jedoch nicht. Ich hatte das nicht bemerkt. –

+0

Sonst wäre auch der Zugriff auf Variablen des umgebenden Scopes nicht möglich, siehe https://docs.oracle.com/javase/tutorial/java/javaOO/lambdadexpresss.html#accessing-local-variables –

+0

Holger, du hast Recht . Meine Annahmen waren falsch. Die Frage steht noch. Gibt es einen Weg, es zu tun? Vielleicht gibt es? – ATrubka

Verwandte Themen