texto mostrar font ejemplo java lambda java-8

mostrar - ¿Qué es un ''tipo SAM'' en Java?



mostrar texto en jlabel java (1)

Al leer las especificaciones de Java-8, sigo viendo referencias a ''tipos de SAM''. No he podido encontrar una explicación clara de lo que es esto.

¿Qué es un tipo de SAM y cuál es un escenario de ejemplo de cuándo se podría usar?


Para resumir cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3.html 1 en caso de que alguna vez pase, "SAM" significa "método abstracto único" y "tipo SAM" se refiere a interfaces como Runnable , Callable , etc. Expresiones Lambda, una nueva característica en Java 8 , se consideran un tipo SAM y se pueden convertir libremente en ellos.

Por ejemplo, con una interfaz como esta:

public interface Callable<T> { public T call(); }

Puede declarar un Callable utilizando expresiones lambda como esta:

Callable<String> strCallable = () -> "Hello world!"; System.out.println(strCallable.call()); // prints "Hello world!"

Las expresiones lambda en este contexto son principalmente azúcar sintáctica. Se ven mejor en el código que las clases anónimas y son menos restrictivos en la nomenclatura de métodos. Toma este ejemplo del enlace:

class Person { private final String name; private final int age; public static int compareByAge(Person a, Person b) { ... } public static int compareByName(Person a, Person b) { ... } } Person[] people = ... Arrays.sort(people, Person::compareByAge);

Esto crea un Comparator utilizando un método específico que no comparte el mismo nombre que Comparator.compare , de esa manera no tiene que seguir la nomenclatura de métodos de la interfaz y puede tener varias anulaciones de comparación en una clase, luego crear los comparadores sobre la marcha a través de las expresiones lambda.

Yendo más profundo ...

En un nivel más profundo, Java implementa estos usando la instrucción invokedynamic bytecode agregada en Java 7. Dije antes que declarar un Lambda crea una instancia de Callable o Comparable similar a una clase anónima, pero eso no es estrictamente cierto. En cambio, la primera vez que se llama a invokedynamic , crea un controlador de función Lambda utilizando el método LambdaMetafactory.metafactory , luego utiliza esta instancia en caché en futuras invocaciones del Lambda. Se puede encontrar más información en esta respuesta .

Este enfoque es complejo e incluso incluye código que puede leer valores primitivos y referencias directamente de la memoria de la pila para pasar a su código Lambda (por ejemplo, para moverse necesitando asignar una matriz Object[] para invocar su Lambda), pero permite futuras iteraciones de la implementación de Lambda para reemplazar implementaciones antiguas sin tener que preocuparse por la compatibilidad con bytecode. Si los ingenieros de Oracle cambian la implementación subyacente de Lambda en una versión más nueva de la JVM, Lambdas compilada en una JVM anterior usará automáticamente la implementación más nueva sin ningún cambio por parte del desarrollador.

1 La sintaxis en el enlace está desactualizada. Eche un vistazo al Lambda Expressions Java Trail para ver la sintaxis actual.