Les expressions Lambda ne changent pas l'ensemble des problèmes que vous pouvez résoudre avec Java en général, mais facilitent certainement la résolution de certains problèmes, juste pour la même raison que nous ne programmons plus en langage assembleur. La suppression des tâches redondantes du travail du programmeur facilite la vie et permet de faire des choses que vous ne toucheriez même pas autrement, juste pour la quantité de code que vous auriez à produire (manuellement).
Mais les expressions lambda ne sont pas seulement de sauver des lignes de code. Les expressions Lambda vous permettent de définir des fonctions , ce pour quoi vous pouvez auparavant utiliser des classes internes anonymes comme solution de contournement, c'est pourquoi vous pouvez remplacer les classes internes anonymes dans ces cas, mais pas en général.
Plus particulièrement, les expressions lambda sont définies indépendamment de l'interface fonctionnelle vers laquelle elles seront converties, il n'y a donc pas de membres hérités auxquels ils pourraient accéder, de plus, elles ne peuvent pas accéder à l'instance du type implémentant l'interface fonctionnelle. Dans une expression lambda, this
et super
ont la même signification que dans le contexte environnant, voir aussi cette réponse . De plus, vous ne pouvez pas créer de nouvelles variables locales occultant les variables locales du contexte environnant. Pour la tâche prévue de définir une fonction, cela supprime un grand nombre de sources d'erreur, mais cela implique également que pour d'autres cas d'utilisation, il peut y avoir des classes internes anonymes qui ne peuvent pas être converties en une expression lambda, même si vous implémentez une interface fonctionnelle.
De plus, la construction new Type() { … }
garantit de produire une nouvelle instance distincte (comme new
toujours). Les instances de classe interne anonymes conservent toujours une référence à leur instance externe si elles sont créées dans un non- static
contexte. En revanche, les expressions lambda capturent une référence uniquement this
lorsque cela est nécessaire, c'est-à-dire si elles y accèdent this
ou si elles ne sont pas static
membres. Et ils produisent des instances d'une identité intentionnellement non spécifiée, ce qui permet à l'implémentation de décider au moment de l'exécution s'il faut réutiliser les instances existantes (voir aussi « Une expression lambda crée-t-elle un objet sur le tas à chaque exécution? »).
Ces différences s'appliquent à votre exemple. Votre construction de classe interne anonyme produira toujours une nouvelle instance, elle peut également capturer une référence à l'instance externe, tandis que votre (Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName())
est une expression lambda non capturante qui évaluera à un singleton dans les implémentations typiques. De plus, il ne produit pas de .class
fichier sur votre disque dur.
Compte tenu des différences concernant à la fois la sémantique et les performances, les expressions lambda peuvent changer la façon dont les programmeurs résoudront certains problèmes à l'avenir, bien sûr, également en raison des nouvelles API englobant des idées de programmation fonctionnelle utilisant les nouvelles fonctionnalités du langage. Voir aussi Expression lambda Java 8 et valeurs de première classe .
(o1, o2) -> o1.getName().compareTo(o2.getName())