Представленный в Java 8, функциональный интерфейс — это просто интерфейс, который имеет ровно один абстрактный метод. Узнайте больше о функциональных интерфейсах в этом руководстве.
1. Что такое функциональный интерфейс?
1.1. Разрешен только один абстрактный метод.
Функциональные интерфейсы — это новые дополнения в Java 8. Как правило, функциональный интерфейс может содержать ровно один абстрактный метод. Эти функциональные интерфейсы также называются интерфейсами Single Abstract Method(SAM Interfaces).
Помимо одного абстрактного метода, функциональный интерфейс может также иметь следующие методы, которые не учитываются при определении его как функционального интерфейса.
- Методы по умолчанию
- Статические методы
- Публичные методы, унаследованные от класса Object
1.2 Реализовано с помощью лямбда-выражений
В Java лямбда-выражения могут использоваться для представления экземпляра функционального интерфейса. Например, интерфейс Comparator является функциональным интерфейсом.
@FunctionalInterfacepublic interface Comparator<T> {int compare(T o1, T o2);boolean equals(Object obj);//and multiple default methods...}
Интерфейс Comparator имеет только два абстрактных метода compare() и equals(). Но equals() унаследован от класса Object, поэтому он не учитывается. За исключением этих двух методов, все остальные методы являются методами по умолчанию. Поэтому Comparator может быть объявлен как функциональный интерфейс.
Программа на Java для реализации компаратора с использованием лямбда-выражения.
//Compare by IdComparator<Employee> compareById = Comparator.comparing(e -> e.getId());Comparator<Employee> compareByFirstName = Comparator.comparing(e -> e.getFirstName());
2. Аннотация @FunctionalInterface
В Java 8 появилась аннотация @FunctionalInterface, которая помечает интерфейс как функциональный. Основное применение этой аннотации — ошибки на уровне компилятора, когда интерфейс нарушает контракты ровно одного абстрактного метода.
Обратите внимание, что использование аннотации @FunctionalInterface необязательно.
Если интерфейс имеет один абстрактный метод и не имеет аннотации @FunctionalInterface, интерфейс все равно является функциональным интерфейсом и может быть целевым типом для лямбда-выражений.
Наличие аннотации защищает нас от непреднамеренного изменения функционального интерфейса в нефункциональный, поскольку компилятор это обнаружит.
Давайте создадим наш первый функциональный интерфейс. Обратите внимание, что методы в интерфейсе по умолчанию абстрактны.
@FunctionalInterfacepublic interface MyFirstFunctionalInterface{public void firstWork();}
Давайте попробуем добавить еще один абстрактный метод:
@FunctionalInterfacepublic interface MyFirstFunctionalInterface{public void firstWork();public void doSomeMoreWork(); //error}
Приведенный выше код приведет к ошибке компиляции:
Неожиданная аннотация @FunctionalInterface@FunctionalInterface ^ MyFirstFunctionalInterface не является функциональным интерфейсомВ интерфейсе MyFirstFunctionalInterface найдено несколько непереопределяющих абстрактных методов

Подробнее: Общие функциональные интерфейсы
3. Функциональные интерфейсы в JDK
Ниже приведен список наиболее часто используемых функциональных интерфейсов Java.
- Runnable: содержит только метод run().
- Comparable: содержит только метод compareTo().
- ActionListener: содержит только метод actionPerformed().
- Вызываемый: содержит только метод call().
- Предикат : функция с логическим значением, которая принимает аргумент и возвращает значение «истина» или «ложь».
- BiPredicate: предикат с двумя аргументами.
- Потребитель: операция, которая принимает аргумент, выполняет над ним операции и не возвращает никакого результата.
- BiConsumer: потребитель с двумя аргументами.
- Поставщик: поставщик, который возвращает значение.
- Функция: принимает аргумент типа T и возвращает результат типа R.
- BiFunction<T, U, R>: принимает два аргумента типов T и U и возвращает результат типа R.
4. Демонстрация
Давайте рассмотрим краткий пример создания и использования функциональных интерфейсов в Java.
Мы используем функциональный интерфейс Function для создания формулы для математических квадратов.
Function<Integer, Integer> square = x -> x * x;
Интерфейс Function имеет один абстрактный метод apply(), который мы реализовали выше. Мы можем выполнить указанный выше метод следующим образом:
System.out.println( square.apply(5) ); //Prints 25
5. Заключение
В этом уроке мы научились создавать и управлять функциональными интерфейсами в Java. Мы узнали, что функциональный интерфейс имеет только один абстрактный метод и они могут быть реализованы с помощью лямбда-выражений.
Мы также увидели, что JDK предоставляет существующие функциональные интерфейсы, и, наконец, как создать и использовать функциональный интерфейс.