Le JLS précise que
Si le résultat du type de fonction est void, le corps lambda est soit une expression d'instruction (§14.8), soit un bloc compatible void.
Voyons maintenant cela en détail,
Puisque votre takeBiConsumer
méthode est de type void, la réception lambda new String("hi")
l'interprétera comme un bloc comme
{
new String("hi");
}
qui est valide dans le vide, d'où la première compilation de cas.
Cependant, dans le cas où le lambda est -> "hi"
, un bloc tel que
{
"hi";
}
n'est pas une syntaxe valide en java. Par conséquent, la seule chose à faire avec "hi" est d'essayer de le renvoyer.
{
return "hi";
}
qui n'est pas valide dans le vide et expliquer le message d'erreur
incompatible types: bad return type in lambda expression
java.lang.String cannot be converted to void
Pour une meilleure compréhension, notez que si vous changez le type de takeBiConsumer
en String, -> "hi"
sera valide car il essaiera simplement de renvoyer directement la chaîne.
Notez qu'au début, j'ai pensé que l'erreur était due au fait que le lambda était dans un mauvais contexte d'invocation, je vais donc partager cette possibilité avec la communauté:
JLS 15.27
Il s'agit d'une erreur de compilation si une expression lambda se produit dans un programme dans un endroit autre qu'un contexte d'affectation (§5.2), un contexte d'appel (§5.3) ou un contexte de transtypage (§5.5).
Cependant dans notre cas, nous sommes dans un contexte d'invocation qui est correct.