Il JLS lo specifica
Se il risultato del tipo di funzione è void, il corpo lambda può essere un'espressione di istruzione (§14.8) o un blocco compatibile con il void.
Vediamolo ora in dettaglio,
Poiché il tuo takeBiConsumer
metodo è di tipo void, la ricezione lambda new String("hi")
lo interpreterà come un blocco simile
{
new String("hi");
}
che è valido in un vuoto, da qui la compilazione del primo caso.
Tuttavia, nel caso in cui si trovi lambda -> "hi"
, un blocco come
{
"hi";
}
non è una sintassi valida in java. Quindi l'unica cosa da fare con "ciao" è provare a restituirlo.
{
return "hi";
}
che non è valido in un vuoto e spiega il messaggio di errore
incompatible types: bad return type in lambda expression
java.lang.String cannot be converted to void
Per una migliore comprensione, nota che se cambi il tipo di takeBiConsumer
in String, -> "hi"
sarà valido in quanto cercherà semplicemente di restituire direttamente la stringa.
Nota che all'inizio ho pensato che l'errore fosse causato dal fatto che lambda si trova in un contesto di invocazione sbagliato, quindi condividerò questa possibilità con la comunità:
JLS 15.27
È un errore in fase di compilazione se un'espressione lambda si verifica in un programma in un luogo diverso da un contesto di assegnazione (§5.2), un contesto di invocazione (§5.3) o un contesto di casting (§5.5).
Tuttavia, nel nostro caso, siamo in un contesto di invocazione corretto.