with what interfaces implement how exercises java functional-programming java-8 functional-interface

java - what - ¿Por qué no se usa @FunctionalInterface en todas las interfaces en el JDK que califican?



public interface (3)

Bueno, una anotación que documente una intención sería inútil si usted asume que siempre se da esa intención.

Nombró el ejemplo AutoCloseable que obviamente no está destinado a implementarse como una función, ya que hay Runnable que es mucho más conveniente para una función con una firma ()->void . Se pretende que una clase que implementa AutoCloseable administre un recurso externo que las clases anónimas implementadas a través de la expresión lambda no hacen.

Un ejemplo más claro es Comparable , una interface no solo no está pensada para implementarse como una expresión lambda, sino que es imposible implementarla correctamente utilizando una expresión lambda.

Posibles motivos para no marcar una interface con @FunctionalInterface por ejemplo:

  • La interface tiene semántica de lenguaje de programación, por ejemplo, AutoClosable o Iterable (es poco probable que ocurra para sus propias interfaces)
  • No se espera que la interface tenga implementaciones arbitrarias y / o sea más un identificador que la implementación real, por ejemplo, java.net.ProtocolFamily , o java.lang.reflect.GenericArrayType (Tenga en cuenta que este último también heredará una implementación default para getTypeName() ser inútil para implementaciones lambda como confiar en toString() )
  • Las instancias de esta interface deben tener una identidad, por ejemplo, java.net.ProtocolFamily , java.nio.file.WatchEvent.Modifier , etc. Tenga en cuenta que estas son implementadas típicamente por una enum

    Otro ejemplo es java.time.chrono.Era que tiene un solo método abstract , pero su especificación dice "Las instancias de Era podrían compararse utilizando el operador == ".

  • La interface tiene la intención de alterar el comportamiento de una operación para la cual una implementación de la interface sin heredar / implementar nada más no tiene sentido, por ejemplo, java.rmi.server.Unreferenced
  • Es una abstracción de operaciones comunes de clases que deberían tener más que solo estas operaciones, por ejemplo, java.io.Flushable , java.io.Flushable , java.lang.Readable
  • La herencia esperada es parte del contrato y prohíbe las implementaciones de expresiones lambda, por ejemplo, en java.awt : ActiveEvent debe ser implementado por un AWTEvent , PrinterGraphics by a Graphics , lo mismo se aplica a java.awt.print.PrinterGraphics (hey, two interface s para exactamente lo mismo ...), wheras javax.print.FlavorException debe implementarse mediante una subclase javax.print.PrintException
  • No sé si las distintas interfaces del detector de eventos no están marcadas con @FunctionalInterface para simetría con otro detector de eventos de múltiples métodos que no pueden ser interfaces funcionales, pero en realidad los oyentes de eventos son buenos candidatos para las expresiones lambda. Si desea eliminar un escucha en un momento posterior, debe almacenar la instancia pero eso no es diferente, por ejemplo, implementaciones de escucha de clase interna.
  • El mantenedor de la biblioteca tiene una base de código grande con más de 200 tipos de candidatos y no los recursos para discutir para cada interface si debe anotarse y, por lo tanto, se enfoca en los candidatos principales para ser utilizados en un contexto funcional. Estoy seguro de que, por ejemplo, java.io.ObjectInputValidation , java.lang.reflect.InvocationHandler , juc RejectedExecutionHandler & ThreadFactory no sería tan malo como @FunctionalInterface pero no tengo idea de si, por ejemplo, java.security.spec.ECField hace un buen candidato Cuanto más general sea la biblioteca, es más probable que los usuarios de la biblioteca puedan responder a esa pregunta para una interface particular interface que estén interesados, pero sería injusto insistir en que el responsable de la biblioteca responda a todas las interfaces.

    En este contexto, tiene más sentido ver la presencia de un @FunctionalInterface como un mensaje de que una interface está destinada a ser utilizada junto con las expresiones lambda que a tratar la ausencia de la anotación como un indicador de que no está destinada a ser utilizada. de esta manera. Esto es exactamente como el compilador lo maneja, puede implementar cada interface método abstracto usando una expresión lambda, pero cuando la anotación está presente, se asegurará de que pueda usar esta interface de esta manera.

Java 8 nos dio muchas maneras divertidas de usar interfaces funcionales y con ellas una nueva anotación: @FunctionalInterface . Su trabajo es decirle al compilador que nos grite si no nos atenemos a las reglas de una interfaz funcional (solo un método abstracto que deba anularse).

Hay 43 interfaces en el paquete java.util.function con esta anotación. Una búsqueda de jdk.1.8.0 / src para @FunctionalInterface solo @FunctionalInterface 57 hits. ¿Por qué las otras interfaces (como AutoCloseable) que podrían haber agregado @FunctionalInterface aún faltan?

Hay un poco de un vago indicio en la @FunctionalInterface las @FunctionalInterface :

"Un tipo de anotación informativa utilizado para indicar que una declaración de tipo de interfaz pretende ser una interfaz funcional"

¿Hay alguna buena razón para NO tener la intención de que una interfaz que he diseñado (que puede ser simplemente una interfaz funcional) no se use como una? ¿Está dejando de lado una indicación de algo además de no darse cuenta de que podría haber sido agregado?

¿La adición de métodos abstractos a cualquier interfaz publicada no va a perjudicar a nadie que la implemente, funcional o no? Me siento cínico asumiendo que simplemente no se molestaron en cazarlos, pero ¿qué otra explicación hay?

Actualización : Después de revisar "¿Debería ser ''Comparable'' una ''interfaz funcional''?" Me parece que todavía tengo preguntas molestas. Cuando una interfaz de método único y una interfaz funcional son estructuralmente idénticas, ¿qué se deja de ser diferente? ¿Es la diferencia simplemente los nombres? Comparable y Comparator están lo suficientemente cerca semánticamente. Resulta que son diferentes estructuralmente, aunque todavía no es el mejor ejemplo ...

¿Existe un caso en el que una SMI es estructuralmente buena para usar como una interfaz funcional pero aún no se recomienda sobre el significado semántico del nombre de la interfaz y el método? O tal vez el contrato implícito por los Javadocs?


En java 8, la interfaz funcional es una interfaz que tiene exactamente un método abstracto llamado método funcional con el que los parámetros de la expresión lambda y los tipos de retorno coinciden.

El java.util.function contiene interfaces funcionales de uso general utilizadas por JDK y también disponibles para usuarios finales . Si bien no son el conjunto completo de interfaces funcionales a las que pueden ser aplicables las expresiones lambda, proporcionan el suficiente para cubrir los requisitos comunes. Usted es libre de crear sus propias interfaces funcionales siempre que los conjuntos existentes no sean suficientes.

Hay muchas interfaces disponibles que merecen ser designadas como interfaz funcional, pero el paquete java.util.function ya proporciona interfaces funcionales para casi todos nuestros propósitos.

Por ejemplo, mira en el siguiente código.

public interface Comparable<T> { public int compareTo(T o); } @FunctionalInterface public interface ToIntFunction<T> { int applyAsInt(T value); } public static void main(String[] args){ ToIntFunction<String> f = str -> Integer.parseInt(str); Comparable<String> c = str -> Integer.parseInt(str); }

Comparable también puede tomar un objeto y obtener algún valor de tipo int, pero se proporciona una interfaz dedicada más general ToIntFunction para realizar esta tarea. No existe una regla tan @FunctionalInterface que todas las interfaces que merecen se deben anotar con @FunctionalInterface pero para obtener la ventaja de la función lambda, la interfaz debe cumplir todos los criterios definidos por FunctionalInterface.


Expansión planificada. El hecho de que una interfaz cumpla con los requisitos de un SMI ahora no significa que la expansión no sea necesaria más adelante.