Почему я не могу назначить лямбду объекту?

Я пытался привязать лямбда к типу объекта:

Object f = ()->{};

И это дает мне ошибку:

 The target type of this expression must be a functional interface

Почему это происходит и как это сделать?

Ответ 1

Это невозможно. В соответствии с сообщением об ошибке Object не является функциональным интерфейсом, то есть интерфейсом с одним общедоступным методом, поэтому вам нужно использовать ссылочный тип, например,

Runnable r = () -> {}; 

Ответ 2

Это происходит потому, что на языке Java нет "лямбда-типа".

Когда компилятор видит лямбда-выражение, он попытается преобразовать его в экземпляр типа функционального интерфейса, который вы пытаетесь настроить. Это просто синтаксис сахара.

Компилятор может преобразовывать только лямбда-выражения в типы, которые объявляют один абстрактный метод. Это то, что он называет "функциональным интерфейсом". И Object явно не подходит.

Если вы это сделаете:

Runnable f = (/*args*/) -> {/*body*/};

Затем Java сможет преобразовать лямбда-выражение в экземпляр анонимного класса, который расширяет Runnable. По сути, это то же самое, что писать:

Runnable f = new Runnable() {
    public void run(/*args*/) {
        /*body*/
    }
};

Я добавил комментарии /*args*/ и /*body*/, чтобы сделать его более понятным, но они не нужны.

Java может вывести, что выражение lamba должно быть типа Runnable из-за сигнатуры типа f. Но в мире Java нет "лямбда-типа".

Если вы пытаетесь создать универсальную функцию, которая ничего не делает на Java, вы не можете. Java 100% статически типизирована и ориентирована на объекты.

Существуют некоторые различия между анонимными внутренними классами и выражениями lambdas, но вы можете смотреть на них, поскольку они были просто синтаксическим сахаром для создания объектов типа с помощью одного абстрактного метода.