Je suis tombé sur un nouveau terme en Java 8: "interface fonctionnelle". Je n'ai pu en trouver qu'une seule utilisation en travaillant avec des expressions lambda .
Java 8 fournit des interfaces fonctionnelles intégrées et si nous voulons définir une interface fonctionnelle, nous pouvons utiliser l' @FunctionalInterface
annotation. Cela nous permettra de ne déclarer qu'une seule méthode dans l'interface.
Par exemple:
@FunctionalInterface
interface MathOperation {
int operation(int a, int b);
}
Dans quelle mesure est-il utile dans Java 8 autre que de simplement travailler avec des expressions lambda ?
(La question ici est différente de celle que j'ai posée. Elle demande pourquoi nous avons besoin d'interfaces fonctionnelles tout en travaillant avec des expressions lambda. Ma question est: pourquoi d'autres utilisations des interfaces fonctionnelles ont-elles en plus des expressions lambda?)
Réponses:
@FunctionalInterface
L'annotation est utile pour vérifier le temps de compilation de votre code. Vous ne pouvez pas avoir plus d'une méthode en plusstatic
,default
et des méthodes abstraites qui remplacent des méthodesObject
dans votre@FunctionalInterface
interface ou toute autre interface utilisée comme interface fonctionnelle.Mais vous pouvez utiliser des lambdas sans cette annotation ainsi que vous pouvez remplacer des méthodes sans
@Override
annotation.À partir de documents
Cela peut être utilisé dans l'expression lambda:
Cela ne peut pas être utilisé dans l'expression lambda:
Mais cela donnera une erreur de compilation :
la source
java.lang.Object
dans une interface fonctionnelle.public
méthode en plusstatic
etdefault
»…La documentation fait en effet une différence entre l'objectif
et le cas d'utilisation
dont la formulation n'exclut pas d'autres cas d'utilisation en général. Étant donné que l'objectif principal est d'indiquer une interface fonctionnelle , votre question réelle se résume à "Y a-t-il d'autres cas d'utilisation d' interfaces fonctionnelles autres que les expressions lambda et les références de méthode / constructeur?"
Étant donné que l'interface fonctionnelle est une construction de langage Java définie par la spécification du langage Java, seule cette spécification peut répondre à cette question:
JLS §9.8. Interfaces fonctionnelles :
Ainsi, la spécification du langage Java ne dit pas le contraire, le seul cas d'utilisation mentionné dans cette section est celui de la création d'instances d'interface avec des expressions de référence de méthode et des expressions lambda. (Cela inclut les références de constructeur car elles sont notées comme une forme d'expression de référence de méthode dans la spécification).
Donc, en une phrase, non, il n'y a pas d'autre cas d'utilisation pour Java 8.
la source
public static String generateTaskId()
par rapport à le rendre plus «fonctionnel», quelqu'un d'autre a choisi de l'écrire commepublic class TaskIdSupplier implements Supplier<String>
avec laget
méthode utilisant le mise en œuvre de la génération existante. Est-ce une mauvaise utilisation des interfaces fonctionnelles, en particulier la réutilisationSupplier
du composant intégré de JDK? PS: Je n'ai pas pu trouver un meilleur endroit / Q & A pour demander cela. Heureux de migrer si vous le suggérez.TaskIdSupplier
. Maintenant, la question est de savoir pourquoi vous avez créé la classe nommée. Il existe des scénarios où un tel type nommé est nécessaire, par exemple lorsque vous souhaitez prendre en charge la recherche de l'implémentation viaServiceLoader
. Il n'y a rien de mal à le laisser mettre en œuvreSupplier
alors. Mais lorsque vous n'en avez pas besoin, ne le créez pas. Lorsque vous n'avez besoin que d'unSupplier<String>
, il est déjà suffisant d'utiliserDeclaringClass::generateTaskId
et éliminer le besoin d'une classe explicite est le but de cette fonctionnalité de langage.TaskIdSupplier
mise en œuvre en valait la peine, mais le concept deServiceLoader
totalement sauté de mon esprit. Nous avons rencontré quelques questions lors de ces discussions que nous avions telles que A quoi sert l' existence deSupplier
'spublic
quand on peut aller de l'avant et développer ses propres interfaces? et pourquoi ne pas avoirpublic static Supplier<String> TASK_ID_SUPPLIER = () ->...
comme constante globale? . (1/2)variable.genericMethodName(args)
place demeaningfulMethodName(args)
. L'utilisation d'un type de classe pour représenter une fonction, que ce soit via une référence d'expression / méthode lambda ou une classe créée manuellement, n'est qu'un moyen de transmettre la fonction (en l'absence de vrais types de fonction en Java). Cela ne devrait être fait qu'en cas de besoin.Comme d'autres l'ont dit, une interface fonctionnelle est une interface qui expose une méthode. Il peut avoir plusieurs méthodes, mais toutes les autres doivent avoir une implémentation par défaut. La raison pour laquelle on l'appelle "interface fonctionnelle" est qu'elle agit effectivement comme une fonction. Puisque vous pouvez passer des interfaces en tant que paramètres, cela signifie que les fonctions sont désormais des «citoyens de premier ordre» comme dans les langages de programmation fonctionnels. Cela présente de nombreux avantages, et vous les verrez beaucoup lorsque vous utilisez l'API Stream. Bien sûr, les expressions lambda en sont la principale utilisation évidente.
la source
Pas du tout. Les expressions Lambda sont le seul et unique point de cette annotation.
la source
@Override
pour faire savoir au compilateur que vous aviez l'intention d'écrire quelque chose qui était "fonctionnel" (et obtenir une erreur si vous avez glissé).Une expression lambda peut être affectée à un type d'interface fonctionnelle, mais il en est de même pour les références de méthode et les classes anonymes.
Une bonne chose au sujet des interfaces fonctionnelles spécifiques
java.util.function
est qu'ils peuvent être composés pour créer de nouvelles fonctions (commeFunction.andThen
etFunction.compose
,Predicate.and
, etc.) en raison des méthodes par défaut pratiques qu'ils contiennent.la source
Une interface avec une seule méthode abstraite est appelée Interface fonctionnelle. Il n'est pas obligatoire d'utiliser @FunctionalInterface, mais il est recommandé de l'utiliser avec des interfaces fonctionnelles pour éviter l'ajout accidentel de méthodes supplémentaires. Si l'interface est annotée avec l'annotation @FunctionalInterface et que nous essayons d'avoir plus d'une méthode abstraite, cela génère une erreur du compilateur.
la source
Interface fonctionnelle:
Exemple 1:
Exemple 2:
Exemple 3:
Annotation Java8 -
@FunctionalInterface
Applications de l'interface fonctionnelle:
Pour apprendre les interfaces fonctionnelles, apprendre les premières méthodes par défaut dans l'interface, et après avoir appris l'interface fonctionnelle, il vous sera facile de comprendre la référence de méthode et l'expression lambda
la source
Vous pouvez utiliser lambda dans Java 8
Pour plus d'informations sur Java Lambdas et FunctionalInterfaces
la source
@FunctionalInterface
est une nouvelle annotation est publiée avec Java 8 et fournit des types de cible pour les expressions lambda et elle est utilisée lors de la vérification de la compilation de votre code.Lorsque vous souhaitez l'utiliser:
1- Votre interface ne doit pas avoir plus d'une méthode abstraite, sinon une erreur de compilation sera donnée.
1- Votre interface doit être pure, ce qui signifie que l'interface fonctionnelle est destinée à être implémentée par des classes sans état, exmple de pure est
Comparator
interface car elle ne dépend pas de l'état de l'implémenteur, dans ce cas, aucune erreur de compilation ne sera donnée, mais dans de nombreux cas, vous ne pourra pas utiliser lambda avec ce genre d'interfacesLe
java.util.function
paquet contient diverses interfaces fonctionnelles à usage général tels quePredicate
,Consumer
,Function
, etSupplier
.Veuillez également noter que vous pouvez utiliser des lambdas sans cette annotation.
la source
À côté d'autres réponses, je pense que la raison principale pour "pourquoi utiliser l'interface fonctionnelle autrement qu'avec des expressions lambda" peut être liée à la nature du langage Java qui est orienté objet.
Les principaux attributs des expressions Lambda sont: 1. Ils peuvent être transmis 2. et ils peuvent être exécutés à l'avenir à un moment précis (plusieurs fois). Maintenant, pour prendre en charge cette fonctionnalité dans les langues, d'autres langues traitent simplement de cette question.
Par exemple, dans Java Script, une fonction (fonction anonyme ou littéraux de fonction) peut être adressée en tant qu'objet. Ainsi, vous pouvez les créer simplement et ils peuvent également être affectés à une variable et ainsi de suite. Par exemple:
ou via ES6, vous pouvez utiliser une fonction fléchée.
Jusqu'à présent, les concepteurs de langage Java n'ont pas accepté de gérer les fonctionnalités mentionnées de cette manière (techniques de programmation fonctionnelle). Ils croient que le langage Java est orienté objet et doivent donc résoudre ce problème via des techniques orientées objet. Ils ne veulent pas manquer la simplicité et la cohérence du langage Java.
Par conséquent, ils utilisent des interfaces, car lorsqu'un objet d'une interface avec une seule méthode (je veux dire une interface fonctionnelle) est nécessaire, vous pouvez le remplacer par une expression lambda. Tel que:
la source