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, но вы можете смотреть на них, поскольку они были просто синтаксическим сахаром для создания объектов типа с помощью одного абстрактного метода.