В описании вашего вопроса вы говорите, что полученная ошибка: «Тип цели этого выражения должен быть функциональным интерфейсом»;но строка, где вы показываете, что:
System.out.println(today::getTodayDate);//Problem with this one
будет отображать другое сообщение об ошибке.Поэтому я думаю, что требуется более широкое объяснение.
Кажется, вам сначала нужно создать @FunctionInterface
с именем Today
, чтобы этот код работал, что-то вроде:
@FunctionalInterface
interface Today {
LocalDate getTodayDate();
}
Когда этосоздается, это тоже будет работать:
Today today = () -> LocalDate.now();
, что будет эквивалентно:
Today today = LocalDate::now;
Нет реальной необходимости создавать Today
, так как java.util.Supplier<T>
существует и выполняетто же самое - ничего не принимает в качестве входных данных и возвращает T
;но если вы хотите поиграть - вы могли бы.
На самом деле тот факт, что вы ввели этот интерфейс Today
, сделает объяснение немного проще.
Компилятор видит: today::getTodayDate
(в строке System.out.println(today::getTodayDate);
) и должен «понять», что это такое;это может быть по крайней мере две вещи: Today
или java.util.Supplier
- это не может сказать наверняка;именно поэтому говорят, что лямбда-выражения и ссылки на методы являются поли-выражениями - их тип выводится в контексте использования (как и дженерики).Поскольку компилятор не может определить, что это на самом деле, он завершается неудачей.
Вы можете сделать явное приведение к типу для этой компиляции:
System.out.println((Today) today::getTodayDate);
или:
System.out.println((Supplier<LocalDate>) today::getTodayDate);
Но проблема в том, что даже если это компилируется, работает и печатает «что-то» - то, что он действительно печатает, не указано в JLS
и зависит от реализации.