Функциональный интерфейс
1. Что такое функциональный интерфейс
Чтобы иметь возможность использовать лямбда выражения, необходим интерфейс:
public interface Searchable {
boolean test(Car car);
} Searchable s = (Car c) -> c.getCostUSD() > 20000; Лямбда выражения не содержат информацию о том, какой функциональный интерфейс они реализуют.
Тип выражения выводится из контекста, в котором используется лямбда выражение. Этот тип называется целевой тип (target type).
Если лямбда выражение присваивается какому-то интерфейсу, лямбда выражение должно соответствовать синтаксису метода интерфейса.
Одно и то же лямбда выражение может использоваться с разными интерфейсами, если они имеют абстрактные методы, которые совместимы. Например:
interface Searchable {
boolean test(Car car);
}
interface Saleable {
boolean approve(Car car);
}
//...
Searchable s1 = c -> c.getCostUSD() > 20000;
Saleable s2 = c -> c.getCostUSD() > 20000; Функциональный интерфейс (functional interface) – это интерфейс у которого только один абстрактный метод. Функциональный интерфейс может содержать любое количество методов по умолчанию (default) или статических методов. Например:
interface A {
default int defaultMethod() {
return 0;
}
void method();
} Еще один пример функционального интерфейса:
interface B {
default int defaultMethod() {
return 0;
}
default int anotherDefaultMethod() {
return 0;
}
void method();
} Функциональный интерфейс может содержать методы класса Object:
interface A {
boolean equals(Object o);
int hashCode();
String toString();
void method();
} В Java 8 была введена аннотация @FunctionalInterface, которая генерирует ошибку компиляции, если интерфейс не является функциональным:
// This won't compile
@FunctionalInterface
interface A {
void m(int i);
void m(long l);
}
Примеры функциональных интерфейсов: java.lang.Runnable, java.util.Comparator.
2. Лямбда vs анонимные классы
Лямбда выражения являются альтернативой анонимным классам. Но они не одинаковы.
Общее:
- Локальные переменные могут быть использованы только если они final или effective final.
- Разрешается доступ к переменным класса и статическим переменным класса.
- Они не должны выбрасывать больше исключений чем определено в throws метода функционального интерфейса.
Различия:
- Для анонимных классов ключевое слово
thisссылается на сам класс. Для лямбды выражений на внешний класс. - Анонимные классы компилируются во внутренние классы. Но лямбда выражения преобразуются в статические
privateметоды класса, в котором они используютinvokedynamicинструкцию. Лямбда более эффективны, так как не надо загружать еще один класс.
3. Встроенные функциональные интерфейсы
В Java 8 добавлены встроенные функциональные интерфейсы в пакет java.util.function:
Курс 'Java для начинающих' на Udemy
Зарегистрируйтесь или войдите, чтобы иметь возможность оставить комментарий.