2014-04-01 17 views
9

Ho difficoltà a risolvere perché le espressioni lambda sono assegnabili ad alcune interfacce funzionali, ma non ad altre. Un esempio, utilizzando alcune interfacce funzionali dal Metrics library:Interfacce funzionali in Java 8

Gauge<Double> foo =() -> { return null; }; 
RatioGauge bar =() -> { return null; }; 

La seconda istruzione ha un errore di compilazione (in Eclipse):

Il tipo di destinazione di questa espressione deve essere un'interfaccia funzionale

Per quanto ne so, RatioGauge is a functional interface. Mi sto perdendo qualcosa?

+0

** Interfacce ** funzionali? –

+1

Abstract ** class ** non è funzionale ** interfaccia **. – m0skit0

risposta

22

Una classe astratta (anche se ha solo un metodo astratto) non è un'interfaccia funzionale. Solo un'interfaccia può esserlo.

Da JLS 9.8:

Un'interfaccia funzionale è un'interfaccia che ha solo un metodo abstract (a parte i metodi di Object) ... (corsivo)

L'originale l'idea era per consentire che le classi di abstact fossero espresse come lambda; erano chiamati "tipi SAM", che significava "metodo astratto unico". Questo si è rivelato un problema difficile da risolvere in modo efficiente. This thread parla un po 'del perché; fondamentalmente, il costruttore della classe base ha reso difficile.

+1

Questo è un vero peccato poiché le espressioni lambda erano fondamentalmente intese a sostituire le classi anonime e si può creare una classe anonima da un'interfaccia o da una classe astratta. –

+4

@JoshStone Bene, le espressioni lambda non sono mai state progettate per sostituire completamente le classi anonime, ma solo per determinati scenari. –

+0

@RohitJain Esiste una soluzione alternativa in cui è possibile utilizzare un lambda in combinazione con una classe astratta (con un singolo metodo astratto)? –

0

Un'interfaccia di funzione può avere solo il metodo astratto ONE (oltre ai metodi della classe Object).

Il codice sorgente per Gauge.java codice = http://grepcode.com/file/repo1.maven.org/maven2/com.codahale.metrics/metrics-core/3.0.0/com/codahale/metrics/Gauge.java#Gauge

sorgente per RatioGauge.java = http://grepcode.com/file/repo1.maven.org/maven2/com.codahale.metrics/metrics-core/3.0.0/com/codahale/metrics/RatioGauge.java

noti che Gauge.java ha solo un metodo astratto, mentre RatioGauge ha molti metodi.