Nun, es gibt hauptsächlich zwei Unterschiede. Der erste ist mit dem zugrunde liegenden Prozess verbunden, der in Javac und der JVM passiert, und der zweite ist die Syntax.
Bevor wir eine Erklärung geben, wollen wir sehr schnell definieren, was eine Schließung in einer "echten" funktionalen Sprache ist: eine Funktion, die mit ihrer lexikalischen Umgebung und ihrem Speicherkontext einhergeht.
Zuerst wird der Compiler diesen Code auflösen, indem er den Syntaxiq-Kontext "scannt", in dem der Code ausgeführt wird (nicht die Variablen, aber der Code, den Sie schreiben, verursacht statische Tests). Wenn Sie feststellen, dass Sie ein Lambda als Parameter einer Methode schreiben, die auf eine funktionale Schnittstelle wartet, können Sie kompilieren, sodass die JVM den richtigen Codecode zur Ausführung finden kann. In der Tat werden Sie eine Schnittstelle implementieren, die nur eine Signatur im laufenden Betrieb verfügbar macht.
Dann ist die Syntax an sich wichtig, weil sie Ihnen nicht die gleiche Power wie eine anonyme Klasse bietet, in der Sie mehrere Methoden an derselben Stelle implementieren oder überschreiben können.
Das Stück Code in der Frage ist nicht sehr relevant, um den Unterschied zwischen den beiden Konzepten zu sehen, und es verwendet nicht "Schließung" in seiner Gesamtheit. Hier ist ein Stück Code, das helfen te das Potenzial sehen konnte:
public class MyClass
{
// A one method interface.
public static interface Function
{
void execute(int a);
};
// An implementation of Function using the closure and lambda.
public static Function createPrintAddToTenFunction()
{
Integer x = 10;
Function func = (a) -> System.out.println(x + a);
return func;
}
// A basic program.
public static void main(String args[])
{
Function func = createPrintAddToTenFunction();
func.execute(10);
}
}
Diese kompilieren in Java 8 und drucken: 20
Aber es ist etwas seltsam in Java mit Verschluss. Dieses Stück Code kommt aus dem online documentation, 14 Eintrag:
public static void main(String... args) {
StringBuilder message = new StringBuilder();
Runnable r =() -> System.out.println(message);
message.append("Howdy, ");
message.append("world!");
r.run();
}
wird Howdy, world!
Dieser Druck Und das ist genau das, was Sie wollen nicht in einer funktionalen Programmiersprache. Die JVM tut dies, weil Java eine objektorientierte Sprache ist und ziemlich gut darin ist.
In Java verwenden Sie viele Referenzen auf den Heap (die nahe an Zeigern in einer Sprache wie C oder dem noch näher C++ sind). Mit diesem Prinzip können Sie eine im Speicherkontext des Programms initiierte Variable ändern, wenn Sie im Ausführungsstapel einen Verweis darauf eingebettet haben. Das ist das implizite Prinzip, das von der Von Neumann Architecture kommt. Dies unterscheidet sich von einer funktionalen Sprache, die verschiedene Ausführungskontexte ineinander einschließen sollte, die sich subtil unterscheiden und sicherstellen, dass ein von einer Variablen referenzierter Wert nicht durch eine spätere Zuweisung der Variablen modifiziert wird. Aber das ist eine andere Geschichte.
Es ist immer noch eine Instanz einer anonymen Klasse. Und nein, es ist nicht mächtiger. – newacct