Лямбда-литье

Мне было любопытно, почему лямбда с возвращаемым типом не может быть отброшена до Runnable, тогда как ссылка на непустые методы может.

Runnable r1 = () -> 1; // not allowed
// error: incompatible types: bad return type in lambda expression
// int cannot be converted to void

Runnable r2 = ((Supplier)() -> 1)::get; // allowed

Ответ 1

Интерфейс Runnable определяет метод run с типом возвращаемого типа void. В выражении лямбда это означает, что часть, следующая за стрелкой ->, должна быть выражением. Это объясняется в JLS §15.27.3:

Если результат типа функции недействителен, тело лямбда является выражением оператора (§14.8) или блоком, совместимым с void.

JLS $14.5 четко определяет синтаксис оператора. Как объяснялось выше, оно должно быть "ExpressionStatement" (§ 14.8). Глядя туда, вы можете обнаружить, что простой литерал не является адекватным выражением, но вызов метода (даже если он что-то возвращает).