OK “ Be smart, enjoy coding ! ” Agilité Java .NET Web Mobilité Divers Build 201
OK “ Be smart, enjoy coding ! ” Agilité Java .NET Web Mobilité Divers Build 2015 Java 8 – JSR-335 – 1/3 – Expressions Lambda | S... http://blog.soat.fr/2012/11/java-8-jsr-335-13-exp... 1 of 8 11/11/2015 19:48 28 novembre 2012 JAVA 8 – JSR-335 – 1/3 – EXPRESSIONS LAMBDA Par Yohan BESCHI Neuf ans après les Generics et Collections de Java 5, les expressions Lambda seront la nouvelle révolution dans le monde de Java (version 8). Pour le meilleur ou pour le pire… à vous d’en juger ! Le projet Lambda [1] a pour objectif d’accueillir un prototype de l’implémentation de la JSR-335 (Lambda Expressions for the Java Programming Language [2]) qui sera incluse dans la JDK 8, l’implémentation de référence de Java SE 8. Pour une explication généraliste des expressions Lambda (nommées aussi fonctions anonymes ou closures), je vous invite à consulter la page wikipedia consacrée au sujet [3]. Comme nous le verrons par la suite, la JSR-335 n’est pas limitée aux expressions Lambda, elle dé=nit aussi l’aliasing de méthodes et de constructeurs par référence, ainsi que l’ajout de méthodes par défaut dans les interfaces. Note importante : La JSR n’étant pas encore à l’état « =nal », il est possible qu’il y ait des diAérences entre les fonctionnalités décrites dans cet article et les fonctionnalités proposées dans la version =nale. Pour cet article la JDK 8 build b64 avec support des lambdas a été utilisée. Le dernier build peut être téléchargé depuis java.net. L’intégralité des sources est disponible via Github. GETTING STARTED Commençons par un exemple simple, en implémentant une méthode buildMessage(), qui prend une chaîne de caractères en paramètres et qui retourne une chaîne de caractères. Pour que l’article reste lisible, la javadoc, les noms de packages et les imports ont été omis dans tous les exemples. L’un des objectifs des expressions Lambda est d’éliminer la verbosité des classes anonymes. Comme nous pouvons le constater, c’est mission accomplie. L’utilisation d’une classe anonyme prend 5 lignes (6 avec l’annotation @Override ) alors que l’expression Lambda n’en prend qu’une NOUS SOUTENONS SOAT Site Soat Google+ Twitter Soat Twitter Soat Agile Twitter Soat Experts .Net Twitter Soat Experts Java SOAT PARTAGE AppCircle Appli de référence SoGames Appli de référence SoMvc Developpez.com GitHub Soat Happy .Net Son expertise SoPrism YouTube NUAGE DE MOTS CLÉS .NET agile Agilité ASP .NET bytecode C# Cloud conférence devoxx devoxx france 2012 Html5Java Javascript jvm jvmhardcore Kanban Microsoft pjba plume Scrum Silverlight Techdays web Windows 8 Windows Phone AUTHENTIFICATION LICENCE Sauf mention contraire, le contenu de ce blog est mis à disposition selon les termes de la licence Creative Commons. Accueil > Java > Java 8 – JSR-335 – 1/3 – Expressions Lambda 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 / ** * org.isk.gettingstarted.FirstFunctionalInterface.java */ public interface FirstFunctionalInterface { String buildMessage(String msg); } / ** * org.isk.gettingstarted.GettingStartedTest.java */ public class GettingStartedTest { @Test public void oldWayWithAnonymousClass() { final FirstFunctionalInterface firstInterface = new FirstFunctionalInterface() { @Override public String buildMessage(String msg) { return "Hello " + msg; } }; final String string = firstInterface.buildMessage("Carl"); Assert.assertEquals("Hello Carl", string); } @Test public void newWayWithLambdaExpression() { final FirstFunctionalInterface firstInterface = msg -> "Hello " + msg + " with a lambda expression" final String string = firstInterface.buildMessage("John"); Assert.assertEquals("Hello John with a lambda expression", string); } } Java 8 – JSR-335 – 1/3 – Expressions Lambda | S... http://blog.soat.fr/2012/11/java-8-jsr-335-13-exp... 2 of 8 11/11/2015 19:48 seule. A première vue, la structure d’une fonction Lambda est déconcertante. Le nouvel opérateur -> délimite les paramètres du corps de la méthode [paramètres -> corps de la méthode]. Notre méthode : est transformée en : où msg est le paramètre (le type est implicite, mais il peut être explicite si nécessaire), l’opérateur -> marque la =n de la déclaration des paramètres et le début du corps de la méthode. Le mot clé return est aussi absent lorsque le corps de la méthode est une expression. FUNCTIONAL INTERFACES Une interface fonctionnelle est une interface n’ayant qu’une seule méthode abstraite, qui n’appartient pas à la classe Object. De plus, toutes les méthodes doivent être publiques. Il est important de faire la distinction entre une méthode abstraite et une signature de méthode qui, selon la dé=nition de la JLS [4], n’inclue que le nom de la méthode et ses paramètres. La valeur de retour, ainsi que les exceptions, n’en font pas partie. A noter que rien de particulier ne doit être fait pour qu’une interface devienne une interface fonctionnelle, le compilateur a la charge de les identi=er d’après leur structure. La JDK contient déjà des interfaces répondant à cette dé=nition, auparavant nommés SAM Types (Single Abstract Method). Elles sont parfaitement adaptées pour être utilisées avec les nouvelles fonctionnalités Lambda. Les suivantes étant le plus souvent utilisées : java.util.Comparator java.lang.Runnable java.awt.event.ActionListener javax.swing.event.ChangeListener Pour plus de détails sur les interfaces fonctionnelles – notamment sur la résolution de l’héritage d’interfaces -, vous pouvez consulter la JSR – Part A. EXPRESSIONS LAMBDA DÉFINITION En Java, une expression Lambda est une forme de méthode, plus compacte qu’une méthode standard, pour laquelle le nom est implicite (ce n’est jamais une fonction anonyme comme on peut le rencontrer dans d’autres langages puisque nous avons besoin d’une interface fonctionnelle). De plus, les paramètres peuvent être omis, tout comme leur type ou une valeur de retour. Comme évoqué dans la section « Getting Started », le principal problème des classes anonymes est leur verbosité, ce que les expressions Lambda tentent de gommer. Regardons quelques exemples d’expressions Lambda [5] : 1 2 3 public String buildMessage(String msg) { return "Hello " + msg; } 1 msg -> "Hello " + msg + " with a lambda expression"; 1 2 3 4 5 6 7 8 9 10 11 12 13 // Interface fonctionnelle // equals() appartient à la classe java.lang.Object et est publique public interface Comparator<T> { boolean equals(Object obj); int compare(T o1, T o2); } // N’est pas une interface fonctionnelle // Bien que clone() appartienne à la classe java.lang.Object, elle n’est pas publique public interface Foo { int doSomething(); Object clone(); } // 1. Prend un numérique et retourne sa valeur doublée x -> 2 * x // 2. Prend deux int et retourne leur somme (int x, int y) -> x + y // 3. Ne prend pas de paramètres et retourne 42 () -> 42 // 4. Prend une chaîne de caractères, affiche sa valeur et ne retourne rien Java 8 – JSR-335 – 1/3 – Expressions Lambda | S... http://blog.soat.fr/2012/11/java-8-jsr-335-13-exp... 3 of 8 11/11/2015 19:48 Le type des paramètres peut être explicite (exemples 2 et 4) ou implicite (exemples 1 et 5). Cependant, il n’est pas possible de mixer les deux écritures dans une expression Lambda. Les parenthèses entourant un, et un seul, paramètre implicite peuvent être omises (exemples 1 et 5). Le corps de la méthode peut être un bloc (encadré par des accolades, exemple 5) ou une expression (exemples 1, 2, 3 et 4). Si le corps de la méthode est un bloc, il peut retourner une valeur (exemple 5) ou non à l’aide du mot clé return , selon le cas. Si le corps de la méthode est une expression, il peut retourner une valeur (exemples 1,2 et 3) ou non (exemple 4) selon le cas. Le mot clé return est inutile. Attention, le problème de verticalité des classes anonymes ne doit pas être transformé en problème d’horizontalité, comme aurait pu le devenir l’exemple 5 qui pourrait être écrit sur une ligne. CONTEXTE Le type d’une expression Lambda est celui de l’interface contenant la méthode implémentée par l’expression Lambda. Une expression Lambda peut avoir diAérents types dans diAérents contextes. Il n’existe pas comme dans certains langages un type générique Lambda. GENERICS Une interface fonctionnelle peut dé=nir des Generics. En reprenant le tout premier exemple, voici ce qu’on peut malheureusement avoir si l’on en fait mauvais usage : Une méthode prenant un Type générique I et retournant un Type générique O doit être utilisée dans des situations bien précises, telles que nous le verrons dans le troisième article de cette série. Utiliser une telle méthode pour éviter d’avoir à dé=nir une interface fonctionnelle, et avoir le sentiment d’utiliser une fonction anonyme, est considéré comme étant une mauvaise pratique. De même, l’utilisation d’une ellipse en tant que paramètre d’une méthode, et donc d’une expression Lambda, doit être limitée au passage d’un “pseudo” tableau dont tous les objets représentent la même chose (le principe restant que l’on passe des éléments séparés par une virgule, mais dont la représentation dans la méthode ou le corps de l’expression Lambda, est un tableau). La position des objets dans le tableau, ne doit pas avoir d’importance. (String s) -> System.out.println(s) // 5. Prend une collection, récupère sa taille, la vide // et retourne la taille qu’elle avait au début du bloc c -> { int s = c.size(); c.clear(); return s; } 1 2 3 uploads/s3/ expressions-lambda-1-pdf.pdf
Documents similaires










-
38
-
0
-
0
Licence et utilisation
Gratuit pour un usage personnel Attribution requise- Détails
- Publié le Oct 10, 2021
- Catégorie Creative Arts / Ar...
- Langue French
- Taille du fichier 0.3609MB