Java 8 reference method és un dels conceptes que arriben amb les noves expressions lambda que vénen en el JDK 8, anem a explicar-pas a pas. Fins a aquest moment en Java existien dos conceptes fonamentals, les classes i les interfícies.
Amb l’arriba de Java 8 apareixen les expressions lambda:
Aquestes expressions ens permeten una major reutilització del nostre codi ja que en comptes de reutilitzar classes podem simplement reutilitzar funcions. Aquestes es converteixen per dir-ho d’alguna manera en la unitat mínima de codi. Perquè Java pugui integrar aquests conceptes cal assumir que cal realitzar concessions ja que Java només permet el maneig de classes i interfícies. Així doncs les expressions lambda vénen a ser interfícies que únicament suporten un mètode abstracte. En Java 8 ha molts d’aquests interfícies predefinits. Per abordar el nostre exemple ens recolzarem en la interfície Consumer < T > que té un únic mètode que s’anomena accept el qual rep un paràmetre i no torna res. És un dels interfícies funcionals més senzills.
package com.arquitecturajava.lambdareferencias;import java.util.function.Consumer;public class Principal {public static void main(String args) {Consumer<String> consumidor = (x) -> System.out.println(x); consumidor.accept("hola");}}
En aquest cas hem assignat a la interfície funcional Consumer una expressió lambda que encaixa amb ell. Recordem que la interfície rep un paràmetre i no torna res, el resultat imprimirà hola per la consola:
Podem voler tenir una major flexibilitat en el nostre codi i recolzar-nos en un mètode que ens permet variar l’expressió Lambda i el text que vam imprimir.
package com.arquitecturajava.lambdareferencias;import java.util.function.Consumer;public class Principal {public static void main(String args) {Consumer<String> consumidor = (x) -> System.out.println(x);consumidor.accept("hola");procesar ((x)->System.out.println(x),"hola2");}public static <T> void procesar(Consumer<T> expresion, T mensaje) {expresion.accept(mensaje);}}
el resultat serà similar:
Java 8 Reference Method
Ara bé les expressions lambda ens permeten afegir més flexibilitat a el codi. Per exemple podem disposar d’un altre mètode imprimir a la mateixa classe que compleixi amb el patró de l’expressió lambda (rebi un paràmetre i no retorni res).
Podem utilitzar la sintaxi de Java 8 reference method per invocar el mètode processar recolzant-nos en aquesta nova funció.
package com.arquitecturajava.lambdareferencias;import java.util.function.Consumer;public class Principal {public static void main(String args) {Consumer<String> consumidor = (x) -> System.out.println(x);consumidor.accept("hola");procesar ((x)->System.out.println(x),"hola2");procesar(Principal::imprimir,"hola3");}public static <T> void procesar(Consumer<T> expresion, T mensaje) {expresion.accept(mensaje);}public static void imprimir(String mensaje) {System.out.println("---------");System.out.println(mensaje);System.out.println("---------");}}
com es pot observar hem fet servir la sintaxi Principal :: imprimir per passar com a referència una funció que es troba en el nostre propi programa .
La consola mostrarà:
Això aportarà una gran flexibilitat a l’mètode ja que si per exemple disposem d’una altra classe que disposi d’un mètode que rebi un paràmetre i no retorni res podrem fer-la servir també:
package com.arquitecturajava.lambdareferencias;public class Impresora {public void imprimir (String mensaje) {System.out.println("imprimiendo impresora");System.out.println(mensaje);System.out.println("imprimiendo impresora");}}
I n aquest cas hem creat la classe impressora, podem utilitzar el seu mètode imprimir com si fos una referència a una expressió lambda.
package com.arquitecturajava.lambdareferencias;import java.util.function.Consumer;public class Principal {public static void main(String args) {Consumer<String> consumidor = (x) -> System.out.println(x);consumidor.accept("hola");procesar ((x)->System.out.println(x),"hola2");procesar(Principal::imprimir,"hola3");Impresora i= new Impresora();procesar(i::imprimir,"hola4");}public static <T> void procesar(Consumer<T> expresion, T mensaje) {expresion.accept(mensaje);}public static void imprimir(String mensaje) {System.out.println("---------");System.out.println(mensaje);System.out.println("---------");}}
El programa Principal imprimirà la funcionalitat de la impressora: