Tout d'abord, il est utile de regarder ce qu'est un Consumer<String>
est en réalité. À partir de la documentation:
Représente une opération qui accepte un seul argument d'entrée et de
renvoie aucun résultat. Contrairement à la plupart des autres interfaces fonctionnelles, de la Consommation
est prévu pour fonctionner à partir d'effets secondaires.
C'est donc une fonction qui accepte une Chaîne de caractères et renvoie rien.
Consumer<String> p = ""::equals;
Compile correctement, car equals
pouvez prendre une Corde (et, en effet, n'importe quel Objet). Le résultat d'égal à égal est tout simplement ignorés.*
p = s -> "".equals(s);
C'est exactement le même, mais avec une syntaxe différente. Le compilateur ne sait pas à ajouter un implicite return
car Consumer
ne devrait pas renvoyer une valeur. Il serait ajouter un implicite return
si le lambda est un Function<String, Boolean>
si.
p = s -> true;
Cela prend une Chaîne de caractères (s
), mais parce qu' true
est une expression et non une déclaration, le résultat ne peut pas être ignoré de la même manière. Le compilateur doit ajouter un implicite return
car une expression qui ne peuvent pas exister sur son propre. Ainsi, ce n'est avoir un retour: une valeur booléenne. Par conséquent, il n'est pas un Consumer
.**
p = s -> ("".equals(s));
Encore une fois, c'est une expression, pas une déclaration. Ignorant les lambdas pour un moment, vous verrez la ligne System.out.println("Hello");
va de même ne parviennent pas à compiler si vous la mettez entre parenthèses.
*À partir de la spécification:
Si le corps d'un lambda est une déclaration de l'expression (c'est une expression qui aurait permis de rester seul comme un énoncé), il est compatible avec un vide-fonction de production de type; le résultat est tout simplement ignorée.
**À partir de la spécification (merci, Eugène):
Une expression lambda est en harmonie avec un [vide-production] type de fonction si ...
le corps de lambda est une déclaration expression
(§14.8)
ou un vide-compatible bloc.