it-swarm.com.de

Geben Sie die Inferenz in Java 8) ein

Wird die Einführung der neuen Lambda-Notation (siehe z. B. dieser Artikel ) in Java 8) eine Art Typinferenz erfordern?

Wenn ja, wie wirkt sich das neue Typsystem auf die Sprache Java als Ganzes) aus?

30
Giorgio

Es gibt einiges an falschen Informationen in Antwort des Ratschenfreaks und in seinem Kommentarthread. Ich werde hier mit einer Antwort antworten, da ein Kommentar zu klein ist. Da dies schließlich eine Antwort ist, werde ich auch versuchen, die ursprüngliche Frage zu beantworten. (Beachten Sie jedoch, dass ich kein Experte für Typsysteme bin.)

Erstens lauten die kurzen Antworten auf die ursprüngliche Frage Ja und Nein. Ja, Java 8 hat erheblich mehr Typinferenz als Java 7 und Nein, dort) ist kein "neues" Typsystem in Java 8, obwohl es einige geringfügige Änderungen gibt.

Java 8 wird weiterhin statisch typisiert und weist weiterhin die Dichotomie zwischen Klassen und Schnittstellen auf. Es gibt keine neuen Typen wie Funktionstypen. Der Typ eines Lambda ist im Wesentlichen eine "funktionale Schnittstelle", die eine gewöhnliche Schnittstelle mit einer einzelnen abstrakten Methode ist.

Schnittstellen können jetzt Code in Form von Standardmethoden haben, aber das Modell der Einzelvererbung von Klassen und der Mehrfachvererbung von Schnittstellen bleibt dasselbe. Natürlich gibt es einige Anpassungen, z. B. Regeln für die Methodenauflösung bei Vorhandensein von Standardmethoden, aber die Grundlagen bleiben unverändert.

Jeder Typ, der durch Typinferenz abgeleitet wird, kann explizit ausgeschrieben werden. Um das Beispiel von Ratschenfreak zu verwenden,

Collections.<MyClass>sort(list, (a, b) -> { return a.order - b.order; });

ist im Grunde Zucker für

Collections.<MyClass>sort(list,
    (Comparator<MyClass>)((MyClass a, MyClass b) -> { return a.order - b.order; }));

Die Aussage von sparkleshy "Typinferenz erfordert keine Erweiterung des Typsystems" ist grundsätzlich korrekt.

Aber um zu syntaktischem Zucker zurückzukehren, wiederhole ich meine Aussage, dass ein Lambda-Ausdruck kein syntaktischer Zucker für eine anonyme innere Klasse ist. Ratschenfreak erklärte, dass a Der Lambda-Ausdruck wird in eine anonyme Instanziierung der inneren Klasse übersetzt, und Sparkleshy hat lediglich erneut bestätigt, dass ein Lambda syntaktischer Zucker für eine anonyme innere Klasse ist, aber diese Aussagen sind falsch . Sie basieren wahrscheinlich auf veralteten Informationen. Frühe Lambda-Implementierungen haben Lambdas auf diese Weise implementiert, aber die Dinge haben sich geändert.

Lambda-Ausdrücke unterscheiden sich semantisch von inneren Klassen und werden anders als innere Klassen implementiert.

Lambda-Ausdrücke unterscheiden sich in einigen Punkten semantisch von inneren Klassen. Das Auswerten eines Lambda-Ausdrucks muss nicht jedes Mal eine neue Instanz erstellen. Sie haben auch unterschiedliche Erfassungssemantiken, zum Beispiel erfassen sie this unterschiedlich. In einer inneren Klasse ist this die Instanz der inneren Klasse, während in einem Lambda this die einschließende Instanz ist. Folgendes berücksichtigen:

public class CaptureThis {
    void a(Runnable r) { r.run(); }

    void b() {
        a(new Runnable() { public void run() { System.out.println(this); }});
        a(() -> System.out.println(this));
    }

    public String toString() { return "outer"; }

    public static void main(String[] args) { new CaptureThis().b(); }
}

In einem kürzlich veröffentlichten JDK 8-Lambda-Build (ich habe b69 verwendet) sieht die Ausgabe wie folgt aus:

[email protected]
outer

Darüber hinaus werden Lambda-Ausdrücke völlig anders implementiert als innere Klassen. Wenn Sie die disassemblierte Ausgabe vergleichen, werden Sie feststellen, dass der Code der inneren Klasse direkt zur Erstellung und zum Aufruf eines Konstruktors von CaptureThis $ 1 kompiliert wird, während der Lambda-Ausdruck zu einer aufgerufenen dynamischen Anweisung kompiliert wird, die ein Runnable durch nicht angegebene Mittel beschafft. Eine vollständige Erklärung, wie dies funktioniert und warum, finden Sie in Brian Goetz 'JavaOne 2012-Vortrag Lambda: Ein Blick unter die Haube .

47
Stuart Marks