2014-09-11 14 views
9

Sto provando ad apprendere lambda in nuovo Java 8. C'è una cosa interessante. Se il metodo ha la stessa firma dell'interfaccia funzionale, può essere assegnato utilizzando l'API lambdas. Per esempio.lambda con metodi non statici in Java 8

Comparator<Integer> myComp = Integer::compare; 

Questo metodo (Integer.compare) è statico, prende due valori, tutto è perfetto. la firma è la stessa di nel confronto del metodo di interfaccia. Ma questo può essere effettuato con metodi non statici, ad esempio

Comparator<Integer> myComp = Integer::compareTo. 

Questo metodo è non statico (livello di istanza) e, inoltre, richiede un solo valore. Come ho capito, non ci sono metodi non statici in Java, ogni metodo è statico, ma se non è contrassegnato come statico, prende come primo parametro lo this. Come seguendo

compareTo(this,Integer value). 

Sarebbe ragionevole presumere che risultato sarà indefinito causa di confronto dell'oggetto e intero. MA FUNZIONA.

Comparator<Integer> comparator = Integer::compareTo; 
Comparator<Integer> comparator2 = Integer::compare; 
System.out.println(comparator.compare(1,2)); 
System.out.println(comparator2.compare(1,2)); 

Questo funziona allo stesso modo. Ho stack di metodi di chiamata debug. Mentre si chiama il metodo confronta di oggetto comparatore senza creare istanza, this. Il valore è già inizializzato dal primo parametro e naturalmente questo è un riferimento valido all'oggetto.

Quindi la domanda è: come funziona? Durante la chiamata ai controlli del compilatore del metodo, se la classe ha un solo campo che ha lo stesso tipo del primo parametro nel metodo, se la classe ha un compilatore crea implicitamente una nuova istanza della classe con campo inizializzato o come funziona?

+0

correlati: http://stackoverflow.com/questions/22561614/java-8-streams-min-and-max-why-does-this-compile – assylias

risposta

10

Questo perché i lambda non provengono dal mondo orientato agli oggetti.

Quando si assegna a Comparator<Integer> un metodo, l'operazione è eseguire il confronto.

Comparator<Integer> methodOne = Integer::compare; 
Comparator<Integer> methodTwo = Integer::compareTo; 

Questo methodOne.compare(1,2); sarà tradotto per Integer.compare(1,2) è chiamata non-esempio-cattura e si riferiscono alla metodo statico

Questa methodTwo.compare(1,2); sarà tradotto per 1.compareTo(2) si è chiamata istanza-cattura e si riferisce a metodi di istanza.

Il compilatore "conosce" il tipo di metodo a cui si è fatto riferimento in modo che possa elaborare senza errori.

Method reference capture