Tipo di inferenza in Java 8

30

È l'introduzione della nuova notazione lambda (vedi ad esempio questo articolo ) in Java 8 richiederà qualche tipo di inferenza di tipo?

In caso affermativo, in che modo il nuovo sistema di tipi avrà un impatto sulla lingua Java nel suo complesso?

    
posta Giorgio 30.11.2012 - 17:03
fonte

1 risposta

47

C'è un bel po 'di informazioni non corrette nella risposta di freaket crk e nel suo thread di commenti. Risponderò qui in una risposta, poiché un commento è troppo piccolo. Inoltre, poiché questa è una risposta, cercherò di rispondere anche alla domanda originale. (Nota comunque che non sono un esperto di sistemi di tipi.)

Per prima cosa, le risposte brevi alla domanda originale sono Sì e No. Sì, Java 8 avrà un'inferenza di tipo notevolmente maggiore rispetto a Java 7 e No, non c'è un "nuovo" tipo di sistema in Java 8, anche se ci sono alcune modifiche minori.

Java 8 sarà ancora tipizzato staticamente e avrà ancora la dicotomia tra classi e interfacce. Non ci sono nuovi tipi come i tipi di funzione. Il tipo di lambda è essenzialmente una "interfaccia funzionale" che è un'interfaccia ordinaria con un singolo metodo astratto.

Le interfacce ora possono avere il codice sotto forma di metodi predefiniti, ma il modello dell'ereditarietà singola delle classi e dell'ereditarietà multipla delle interfacce rimane lo stesso. Ci sono alcuni aggiustamenti, ovviamente, come le regole per la risoluzione del metodo in presenza di metodi predefiniti, ma i fondamentali sono invariati.

Qualsiasi tipo dedotto dall'inferenza di tipo potrebbe essere scritto esplicitamente. Per utilizzare l'esempio ratchet freak ,

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

è fondamentalmente zucchero per

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

Quindi sparkleshy l'affermazione "l'inferenza di tipo non richiede alcuna estensione del sistema di tipi" è fondamentalmente corretta.

Ma per tornare allo zucchero sintattico, ripeterò la mia affermazione che un'espressione lambda non è zucchero sintattico per una classe interiore anonima. La caratteristica di Ratchet ha dichiarato che un'espressione lambda è tradotta in un anonimo interno istanza di classe, e Sparkleshy ha semplicemente riaffermato che uno zucchero sintattico lambda per una classe interiore anonima, ma queste affermazioni sono errate. Probabilmente si basano su informazioni obsolete. Le prime implementazioni lambda hanno implementato lambda in questo modo, ma le cose sono cambiate.

Le espressioni Lambda sono semanticamente diverse dalle classi interne e sono implementate in modo diverso dalle classi interne.

Le espressioni lambda sono semanticamente diverse dalle classi interne in un paio di modi. La valutazione di un'espressione lambda non ha bisogno di creare una nuova istanza ogni volta. Hanno anche una semantica di cattura diversa, ad esempio, catturano questo in modo diverso. In una classe interna, questa è l'istanza della classe interna, mentre in una lambda, questa è l'istanza allegata. Considera quanto segue:

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 un recente build lambda JDK 8 (ho usato b69 ), l'output sarà simile al seguente:

CaptureThis$1@113de03
outer

Inoltre, le espressioni lambda sono implementate in modo completamente diverso dalle classi interne. Se confronti l'output disassemblato, vedrai che il codice di classe interno si compila direttamente alla creazione e chiama a un costruttore di CaptureQuesto $ 1, mentre l'espressione lambda si compila a un'istruzione invokeynamic che procura un Runnable attraverso mezzi non specificati. Per una spiegazione completa di come funziona e perché, vedere Brian Goetz 'JavaOne 2012 talk Lambda: A Peek Under The Hood .

    
risposta data 07.01.2013 - 01:46
fonte

Leggi altre domande sui tag