Encontré un nuevo término en Java 8: "interfaz funcional". Solo pude encontrar un uso mientras trabajaba con expresiones lambda .
Java 8 proporciona algunas interfaces funcionales integradas y, si queremos definir alguna interfaz funcional, podemos hacer uso de la @FunctionalInterface
anotación. Nos permitirá declarar un solo método en la interfaz.
Por ejemplo:
@FunctionalInterface
interface MathOperation {
int operation(int a, int b);
}
¿Qué tan útil es en Java 8 además de trabajar con expresiones lambda ?
(La pregunta aquí es diferente de la que hice. Pregunta por qué necesitamos interfaces funcionales mientras trabajamos con expresiones lambda. Mi pregunta es: ¿por qué otros usos tienen las interfaces funcionales además de las expresiones lambda?)
Respuestas:
@FunctionalInterface
La anotación es útil para verificar el tiempo de compilación de su código. No puede tener más de un método ademásstatic
,default
y métodos abstractos que anulan los métodosObject
en su@FunctionalInterface
o cualquier otra interfaz utilizada como interfaz funcional.Pero puede usar lambdas sin esta anotación, así como también puede anular métodos sin
@Override
anotación.De documentos
Esto se puede usar en la expresión lambda:
Esto no se puede usar en la expresión lambda:
Pero esto dará error de compilación :
fuente
java.lang.Object
en una interfaz funcional.public
método ademásstatic
ydefault
" ...La documentación realmente hace una diferencia entre el propósito
y el caso de uso
cuya redacción no excluye otros casos de uso en general. Dado que el objetivo principal es indicar una interfaz funcional , su pregunta real se reduce a "¿Hay otros casos de uso para interfaces funcionales que no sean expresiones lambda y referencias de método / constructor?"
Dado que la interfaz funcional es una construcción de lenguaje Java definida por la Especificación del lenguaje Java, solo esa especificación puede responder a esa pregunta:
JLS §9.8. Interfaces funcionales :
Por lo tanto, la Especificación del lenguaje Java no dice lo contrario, el único caso de uso mencionado en esa sección es el de crear instancias de interfaz con expresiones de referencia de método y expresiones lambda. (Esto incluye referencias de constructor, ya que se indican como una forma de expresión de referencia de método en la especificación).
Entonces, en una oración, no, no hay otro caso de uso en Java 8.
fuente
public static String generateTaskId()
en lugar de hacerlo más "funcional"? Otra persona eligió escribirlo comopublic class TaskIdSupplier implements Supplier<String>
con elget
método que usa implementación de generación existente. ¿Es eso un mal uso de las interfaces funcionales, especialmente la reutilizaciónSupplier
del JDK incorporado? PD: No pude encontrar un lugar mejor / Preguntas y respuestas para preguntar esto. Feliz de migrar si pudiera sugerir.TaskIdSupplier
. Ahora, la pregunta es por qué creaste la clase nombrada. Hay escenarios en los que se necesita dicho tipo con nombre, por ejemplo, cuando desea apoyar la búsqueda de la implementación a través deServiceLoader
. No hay nada de malo en dejar que se implementeSupplier
entonces. Pero cuando no lo necesite, no lo cree. Cuando solo necesita unSupplier<String>
, ya es suficiente usarDeclaringClass::generateTaskId
y eliminar la necesidad de una clase explícita es el punto de esta característica del lenguaje.TaskIdSupplier
implementación valiera la pena, pero luego el concepto deServiceLoader
totalmente saltado de mi mente. Encontrado algunas preguntas durante estas discusiones que estaban teniendo como ¿Cuál es el uso deSupplier
'spublic
existencia cuando uno puede seguir adelante y desarrollar sus propias interfaces? y ¿Por qué no tenerpublic static Supplier<String> TASK_ID_SUPPLIER = () ->...
como una constante global? . (1/2)variable.genericMethodName(args)
lugar de hacerlomeaningfulMethodName(args)
. El uso de un tipo de clase para representar una función, ya sea a través de la expresión / método de referencia lambda o una clase creada manualmente, es solo un vehículo para pasar la función (en ausencia de tipos de función verdaderos en Java). Esto solo debe hacerse cuando sea necesario.Como otros han dicho, una interfaz funcional es una interfaz que expone un método. Puede tener más de un método, pero todos los demás deben tener una implementación predeterminada. La razón por la que se llama "interfaz funcional" es porque efectivamente actúa como una función. Como puede pasar interfaces como parámetros, significa que las funciones ahora son "ciudadanos de primera clase" como en los lenguajes de programación funcionales. Esto tiene muchos beneficios, y los verá bastante cuando use la API Stream. Por supuesto, las expresiones lambda son el principal uso obvio para ellas.
fuente
De ningún modo. Las expresiones lambda son el único punto de esa anotación.
fuente
@Override
dejarle saber al compilador que tenía la intención de escribir algo que fuera "funcional" (y obtener un error si se resbala).Se puede asignar una expresión lambda a un tipo de interfaz funcional, pero también se pueden hacer referencias a métodos y clases anónimas.
Lo bueno de las interfaces funcionales específicos en
java.util.function
es que pueden estar compuestos para crear nuevas funciones (comoFunction.andThen
eFunction.compose
,Predicate.and
, etc.) debido a los métodos predeterminados prácticos que contienen.fuente
Una interfaz con un solo método abstracto se llama Interfaz funcional. No es obligatorio usar @FunctionalInterface, pero es una buena práctica usarlo con interfaces funcionales para evitar la adición accidental de métodos adicionales. Si la interfaz se anota con la anotación @FunctionalInterface e intentamos tener más de un método abstracto, arroja un error del compilador.
fuente
Interfaz funcional:
Ejemplo 1:
Ejemplo 2
Ejemplo 3:
Anotación Java8:
@FunctionalInterface
Aplicaciones de la interfaz funcional:
Para aprender interfaces funcionales, aprenda los primeros métodos predeterminados en la interfaz, y después de aprender la interfaz funcional, le resultará fácil comprender la referencia del método y la expresión lambda
fuente
Puedes usar lambda en Java 8
Para más información sobre Java Lambdas y FunctionalInterfaces
fuente
@FunctionalInterface
Es una nueva anotación que se lanza con Java 8 y proporciona tipos de destino para expresiones lambda y se utiliza en la comprobación del tiempo de compilación de su código.Cuando quieras usarlo:
1- Su interfaz no debe tener más de un método abstracto, de lo contrario se generará un error de compilación.
1- Su interfaz debe ser pura, lo que significa que la interfaz funcional está destinada a ser implementada por clases sin estado, por ejemplo, la interfaz de pure es
Comparator
porque no depende del estado de los implementadores, en este caso no se dará ningún error de compilación, pero en muchos casos usted no podrá usar lambda con este tipo de interfacesEl
java.util.function
paquete contiene varias interfaces funcionales de propósito general, tales comoPredicate
,Consumer
,Function
, ySupplier
.También tenga en cuenta que puede usar lambdas sin esta anotación.
fuente
Además de otras respuestas, creo que la razón principal para "por qué usar una interfaz funcional que no sea directamente con expresiones lambda" puede estar relacionada con la naturaleza del lenguaje Java que está orientado a objetos.
Los principales atributos de las expresiones Lambda son: 1. Se pueden pasar alrededor de 2. y se pueden ejecutar en el futuro en un tiempo específico (varias veces). Ahora, para admitir esta función en idiomas, algunos otros idiomas se ocupan simplemente de este asunto.
Por ejemplo, en Java Script, una función (función anónima o literales de función) se puede abordar como un objeto. Por lo tanto, puede crearlos simplemente y también se pueden asignar a una variable y así sucesivamente. Por ejemplo:
o a través de ES6, puede usar una función de flecha.
Hasta ahora, los diseñadores de lenguaje Java no han aceptado manejar las características mencionadas de esta manera (técnicas de programación funcional). Creen que el lenguaje Java está orientado a objetos y, por lo tanto, deberían resolver este problema mediante técnicas orientadas a objetos. No quieren perderse la simplicidad y la coherencia del lenguaje Java.
Por lo tanto, usan interfaces, ya que cuando se necesita un objeto de una interfaz con un solo método (me refiero a la interfaz funcional), puede reemplazarlo con una expresión lambda. Como:
fuente