Может ли Java 8 реализовать интерфейс на лету для ссылки на метод?

Я изучаю новые возможности Java 8.

Я играю на разных примерах и обнаружил странное поведение:

public static void main(String[] args) {       
    method(Test::new);
}
static class Test{
}

private static void method(Supplier<Test> testSupplier){
    Test test = testSupplier.get();
}

Этот код успешно компилируется, но я понятия не имею, как он работает.

Почему Test::new приемлемо в качестве поставщика?

Интерфейс поставщика выглядит очень просто:

@FunctionalInterface
public interface Supplier<T> {    
    T get();
}

3 ответа

Решение

Supplier Интерфейс имеет единственный (функциональный) метод, который:

  • не принимает никаких параметров;
  • возвращает объект.

Поэтому любой метод, соответствующий этим двум пунктам, соответствует функциональному договору Supplier (потому что методы будут иметь одинаковую подпись).

Здесь рассматриваемый метод является ссылкой на метод. Он не принимает параметров и возвращает новый экземпляр Test, Вы можете переписать его так:

method(() -> new Test());

Test::new в синтаксическом сахаре для этого лямбда-выражения.

Test::new является ссылкой на метод. Вместо того, чтобы добавлять новое объяснение, стоит взглянуть на учебник для ссылок на методы, так как он объясняет их довольно хорошо.

Прямой ответ на ваш вопрос таков: Supplier является функциональным интерфейсом - это означает, что он имеет единственный метод, отличный от метода по умолчанию. Конструктор для Test имеет точно такую ​​же подпись (без аргументов, возвращает Test) и так можно напрямую ссылаться на создание анонимного Supplier,

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

Это может быть Function, а не поставщик, если аргумент требуется. Но ссылки на методы могут ссылаться на конструкторы так же, как они ссылаются на методы; у них просто смешное имя (new).

Из Учебного руководства по Java есть четыре вида ссылок на методы:

Добрый пример
------------------------------- ------------------- -----------------
Ссылка на статический метод ConistingClass::staticMethodName
Ссылка на метод экземпляра, содержащий Object::instanceMethodName
конкретного объекта  
Ссылка на метод экземпляра ContainedType::methodName
произвольного объекта 
конкретный тип
Ссылка на конструктор ClassName::new
Другие вопросы по тегам