Il existe un nouveau battage publicitaire avec les expressions lambda tant attendues dans Java 8; tous les 3 jours, un autre article apparaît avec eux sur leur fraîcheur.
D'après ce que j'ai compris, une expression lambda n'est rien de plus qu'une classe interne anonyme avec une seule méthode (au moins au niveau du code octet). En plus de cela, il comporte une autre inférence intéressante, mais je pense que l’équivalent de cela peut être obtenu avec des génériques à un certain niveau (bien sûr, pas de façon aussi nette qu'avec les expressions lambda).
Sachant cela, les expressions lambda vont-elles apporter quelque chose de plus qu'un simple sucre syntaxique en Java? Puis-je créer des classes plus puissantes et flexibles ou d'autres constructions orientées objet avec des expressions lambda qu'il est impossible de construire avec les fonctionnalités de langage actuelles?
la source
this
enOuterClass.this
fait partie du processus de décomposition des expressions lambda en classe anonyme.Réponses:
tl; dr: bien qu’il s’agisse principalement de sucre syntaxique, cette syntaxe plus élégante rend pratique beaucoup de choses qui se terminaient par des lignes infinies et illisibles d’accolades et de parenthèses.
Eh bien, c’est en fait l’inverse, les lambdas sont beaucoup plus âgés que Java. Les classes internes anonymes avec une seule méthode sont (étaient) les Java les plus proches de lambdas. C'est une approximation qui était "assez bonne" pendant un certain temps, mais dont la syntaxe est très désagréable.
En surface, les lambdas de Java 8 ne semblent pas être beaucoup plus que du sucre syntaxique, mais lorsque vous regardez sous la surface, vous voyez des tonnes d'abstractions intéressantes. Par exemple, la spécification JVM traite un lambda de manière tout à fait différente d'un objet "vrai" et, bien que vous puissiez les gérer comme s'ils étaient des objets, la JVM n'est pas obligée de les implémenter en tant que tels.
Mais si toute cette ruse technique est intéressante et pertinente (car elle permet d’optimiser la future machine virtuelle!), Le vrai avantage est "juste" la partie sucre syntaxique.
Quoi de plus facile à lire:
ou:
ou (en utilisant un handle de méthode au lieu d'un lambda):
Le fait que vous puissiez enfin exprimer de manière concise ce qui serait auparavant 5 lignes de code (dont 3 totalement ennuyeuses) apporte un réel changement de ce qui est pratique (mais pas de ce qui est possible, bien sûr).
la source
List
peut contenir n'importe quel objet, unList<String>
peut "seulement" contenir des chaînes. Les génériques ont ajouté une restriction (et l'option de formaliser les restrictions!), Pas un ajout de pouvoir. Presque tout depuis Java 1.1 est du sucre syntaxique. Et ce n'est pas nécessairement une mauvaise chose.List<String>
est juste unList
atout àString
ajouter autour de certaines valeurs de retour. Néanmoins, ils sont extrêmement utiles et rendent le langage beaucoup plus pratique à écrire. Les Lambdas sont un cas similaire.Pour Java, oui, il n’ya rien de mieux qu’un meilleur moyen de créer une classe interne anonyme. Ceci est dû à la décision fondamentale en Java que chaque bit de code octet doit vivre dans une classe spécifique, qui ne peut plus être modifiée maintenant, après des décennies de code hérité à prendre en compte.
Cependant, ce n’est pas ce que les expressions lambda sont vraiment. Dans les formalismes où il s’agit de concepts natifs plutôt que de contorsions, les lambdas sont des éléments fondamentaux; leur syntaxe et l'attitude des gens à leur égard sont très différentes. L'exemple d'une fonction récursive anonyme créée purement à partir de lambdas dans Structure et interprétation des programmes informatiques est capable de changer toute votre conception du calcul. (Cependant, je suis à peu près sûr que cette façon d'apprendre à programmer est juste pour devenir un cas de réussite traditionnel.)
la source
Oui, il ne s'agit que d'un sucre syntaxique, dans le sens où vous écrivez un lambda, vous pouvez réécrire cette expression en tant qu'expression de classe interne anonyme avec une méthode, où la classe implémente l'interface fonctionnelle inférée pour le contexte du lambda, et ce serait exactement équivalent sémantiquement. Et vous pouvez le faire en remplaçant simplement l'expression lambda par l'expression de classe anonyme, sans modifier aucune autre expression ou ligne de code.
la source
this
il faudra convertirOuterClass.this
. Cela ne contredit pas ce que j'ai dit - chaque expression lambda peut être convertie en une expression de classe anonyme sémantiquement équivalente sans modifier quoi que ce soit en dehors de cette expression . Je n'ai pas dit que l'intérieur ne changerait pas.this
lambda fait partie du sucre syntaxique et ne constitue pas une différence de sémantique. Et à propos des différences de mise en œuvre, mise en œuvre! = Sémantique. À propos des différences d'identité d'objet; l'identité de l'objet est extrêmement tangente à la fonctionnalité de lambdas; personne ne vérifie de toute façon l’identité d’objet des classes lambdas / anon car elle n’est pas utile.Joachim Sauer a déjà fait du bon travail en répondant à votre question, mais il n'a fait que faire allusion à quelque chose que je considère comme important. Les Lambdas n'étant pas des classes, ils ne sont pas non plus compilés en tant que tels. Toutes les classes internes anonymes donnent lieu à la création d'un fichier .class qui doit à son tour être chargé par le chargeur de classe. Par conséquent, utiliser Lambdas ne rend pas seulement votre code plus beau, il réduit également la taille de votre code compilé, l'encombrement mémoire de votre ClassLoader et le temps nécessaire au transfert des bits de votre disque dur.
la source
Non ils ne sont pas.
Une autre façon de le dire est que les lambdas sont un moyen non objectif, aussi concis soit-il, de réaliser la même chose qu'une classe anonyme ou, à mon avis, une classe intérieure réaliserait de manière orientée objet.
la source