La programmation fonctionnelle en Java a été développée avec l'introduction des expressions lambda et des interfaces fonctionnelles (à partir de Java 8).
Historique
Avant l'apparition de Java 8, toutes les interfaces se composaient d'un ensemble de méthodes abstraites, et le paradigme était axé sur la POO. Avec l'introduction des interfaces fonctionnelles et des expressions lambda, il est devenu possible d'écrire un code plus concis et de suivre les principes de la PF, ce qui a amélioré la lisibilité et l'expressivité du code.
Problème
Le code lié au traitement des événements, des collections ou de la logique asynchrone devenait obsolète : il était nécessaire de créer des classes séparées ou des classes internes anonymes. Cela compliquait la maintenance et l'évolutivité du code.
Solution
Une interface fonctionnelle est une interface avec exactement une méthode abstraite. Elle peut être utilisée comme cible pour une expression lambda. La bibliothèque standard a introduit des interfaces fonctionnelles typiques, telles que Function<T, R>, Predicate<T>, Supplier<T>, Consumer<T>, ainsi que la possibilité de créer ses propres interfaces.
Exemple de code :
import java.util.function.Function; public class FunctionalExample { public static void main(String[] args) { // Interface fonctionnelle standard Function Function<String, Integer> stringLength = s -> s.length(); System.out.println(stringLength.apply("Java")); // Affichera 4 } }
Caractéristiques clés :
Une interface fonctionnelle peut-elle être déclarée avec plusieurs méthodes abstraites si les autres méthodes ont une implémentation par défaut ou sont statiques ?
Non, une interface fonctionnelle ne peut contenir qu'une seule méthode abstraite. Une méthode par défaut (default) ou statique peut être autorisée.
Peut-on étendre une interface fonctionnelle à partir d'une autre interface avec plusieurs méthodes abstraites ?
Non, si l'interface finale a plus d'une méthode abstraite, elle cesse d'être fonctionnelle et ne peut pas être utilisée pour substituer une expression lambda.
En quoi une interface fonctionnelle Java diffère-t-elle des interfaces SAM dans d'autres langages, comme C# ?
En Java, il n'y a pas de mot clé direct pour la déclaration d'interfaces SAM avant l'introduction de l'annotation @FunctionalInterface. Contrairement à C#, où delegate définit clairement la signature, en Java, un seul méthode abstraite et une annotation optionnelle suffisent pour le compilateur.
@FunctionalInterface — le compilateur ne génère pas d'erreur immédiatement si l'interface cesse d'être fonctionnelle.Dans un grand projet, on a décidé d'utiliser les lambdas partout, y compris là où les entités représentaient des données, sans lien direct avec la logique métier. En conséquence, il était difficile de suivre la logique complexe, les lambdas masquaient les intentions du code, et le débogage devenait difficile.
Avantages :
Inconvénients :
Dans un autre projet, on a soigneusement analysé quelles interfaces conviennent à la PF. On a utilisé Predicate, Function et nos propres interfaces pour le traitement des collections et des événements. Pour les entités et le stockage de données, la PF n'a pas été appliquée.
Avantages :
Inconvénients :