2015-12-01 4 views
8

Mi sono imbattuto in un codice che sto faticando a capire nonostante un po 'di lettura. C'è una chiamata a un metodo che accetta due argomenti, uno dei quali è un Runnable. Piuttosto che passare in un oggetto Runnable sebbene ci sia un lambda.Come Runnable viene creato da Java8 lambda

Ad esempio:

 
public class LambdaTest { 

    private final Lock lock = new ReentrantLock(); 

    @Test 
    public void createRunnableFromLambda() { 
     Locker.runLocked(lock,() -> { 
      System.out.println("hello world"); 
     }); 
    } 

    public static class Locker { 
     public static void runLocked(Lock lock, Runnable block) { 
      lock.lock(); 
      try { 
       block.run(); 
      } finally { 
       lock.unlock(); 
      } 
     } 
    } 
} 

Quindi la mia domanda è: si può spiegare come un Runnable è creato dal lambda, e anche si prega di qualcuno potrebbe spiegare la sintassi () -> {}. In particolare, cosa significano le parentesi()?

grazie.

+3

Tonnellate di guide on-line per Questo. '() -> {}' Il '()' rappresenta i parametri formali per il metodo dichiarato nell'interfaccia funzionale. '{}' è il corpo per quel metodo. '->' separa i parametri dal corpo. –

risposta

24

Un Lambda può essere utilizzato in qualsiasi luogo in cui è richiesta un'interfaccia funzionale. Un'interfaccia funzionale è un'interfaccia con un singolo metodo astratto.

La sintassi lambda utilizzata in questo caso è (arguments) -> {blockOfCodeOrExpression}. La parentesi può essere omessa nel caso di un singolo argomento e le parentesi possono essere omesse nel caso di un singolo comando o espressione.

In altre parole, () -> System.out.println("hello world"); è equivalente a *

new Runnable(){  
    @Override 
    public void run(){ 
    System.out.println("Hello world one!"); 
    } 
}; 

(sono abbastanza sicuro che non è bytecode-equivalente, ma è equivalente in termini di funzionalità)

+5

Un'interfaccia funzionale è un'interfaccia con un singolo metodo ** abstract **. Poiché un 'interface' può ora contenere metodi' static' o 'default', questa differenza è importante. Per essere ancora più specifici, un'interfaccia funzionale ha esattamente un metodo 'abstract' che non sovrascrive un metodo di' java.lang.Object'. Pertanto, ['Comparator'] (https://docs.oracle.com/javase/8/docs/api/?java/util/Comparator.html) è un'interfaccia funzionale, nonostante abbia due metodi' astratti 'come quelli prioritari metodo 'booleano uguale a (Oggetto obj)' di 'java.lang.Object'. E ha molti metodi non "astratti" ... – Holger

+0

Grazie a @Pedro Affonso - così per rispondere alla mia domanda, le parentesi() indicano effettivamente che non ci sono argomenti passati nel blocco di codice. – robjwilkins

+2

_almost_equivalente, ma una differenza importante è ciò che accade se usi la parola chiave 'this' nel corpo. –