Что такое функциональный интерфейс?
Так называется специальная разновидность интерфейса, который определяет тип-функцию, коллбэк.
Чтобы компилятор считал интерфейс функциональным, этот интерфейс должен добавлять единственный абстрактный метод. Вдобавок он может содержать любое количество дефолтных методов с телом. Переобъявление методов класса Object также игнорируется.
Никаких других ограничений на метод не накладывается: он не ограничен в типах аргументов и возвращаемого значения, может иметь любое название и список выбрасываемых исключений (checked и unchecked).
Даже при выполнении всех этих условий, никакие другие разновидности типов кроме interface не могут считаться функциональными интерфейсами.
Дополнительно функциональный интерфейс принято помечать аннотацией @FunctionalInterface . Наличие этой аннотации не необходимо, но оно даёт дополнительную валидацию: её присутствие на нефункциональном типе спровоцирует ошибку компиляции.
Типичные примеры функциональных интерфейсов: Callable , Supplier , Comparable .
Java functional interfaces
Функциональный интерфейс в Java – это интерфейс, который содержит только 1 абстрактный метод. Основное назначение – использование в лямбда выражениях и method reference.
Наличие 1 абстрактного метода — это единственное условие, таким образом функциональный интерфейс может содержать так же default и static методы. К функциональному интерфейсу можно добавить аннотацию @FunctionalInterface. Это не обязательно, но при наличии данной аннотации код не скомпилируется, если будет больше или меньше, чем 1 абстрактный метод. Рекомендуется добавлять @FunctionalInterface. Это позволит использовать интерфейс в лямбда выражениях, не остерегаясь того, что кто-то добавит в интерфейс новый абстрактный метод и он перестанет быть функциональным. В Java есть встроенные функциональные интерфейсы, размещенные в пакете java.util.function .
Не буду останавливаться на них подробно. Отмечу, что наиболее часто используются: Consumer , Function , Predicate , Supplier , UnaryOperator и их Bi – формы. Подробнее можно посмотреть на странице документации: Package java.util.function
import java.util.function.Predicate; //Определяем свой функциональный интерфейс @FunctionalInterface interface MyPredicate < boolean test(Integer value); >public class Tester < public static void main(String[] args) throws Exception < MyPredicate myPredicate = x ->x > 0; System.out.println(myPredicate.test(10)); //true //Аналогично, но используется встроенный функциональный интерфейс java.util.function.Predicate Predicate predicate = x -> x > 0; System.out.println(predicate.test(-10)); //false > >
Но оказывается есть один тонкий момент, описанный в Java Language Specification: “interfaces do not inherit from Object, but rather implicitly declare many of the same methods as Object.” Это означает, что функциональные интерфейсы могут содержать дополнительно абстрактные методы, определенные в классе Object . Код ниже валиден, ошибок компиляции и времени выполнения не будет:
@FunctionalInterface public interface Comparator < int compare(T o1, T o2); boolean equals(Object obj); // другие default или static методы >
Функциональный интерфейс (Functional Interface) — Java: Функции
В Java все реализуется через классы, даже если снаружи кажется что это не так. Лямбда-функции не исключение. Для того чтобы иметь возможность определять лямбда-функции и создавать методы, которые умеют с ними работать, нужно разобраться с функциональными интерфейсами. Об этом мы и поговорим в нашем уроке.
Функциональный интерфейс – это интерфейс с единственным абстрактным методом. Он «под капотом» используется как тип для соответствующих ему лямбда-функций. Создадим для примера такой интерфейс:
@FunctionalInterface public interface Transformer // Имя метода может быть любым // Количество параметров может быть любым String apply(String input); >
Теперь мы можем определять лямбда-функции, соответствующие этому интерфейсу, записывать их в переменные и вызывать.
public class LambdaDemo public static void main(String[] args) Transformer upperCaseTransformer = (input) -> input.toUpperCase(); var result = upperCaseTransformer.apply("hello"); System.out.println(result); // Outputs: HELLO > >
Из кода выше мы видим, что лямбда-функция это объект, где методом является определение лямбда-функции. Это значит, что мы без проблем можем описывать их в параметрах методов.
public class LambdaDemo // Метод, который принимает лямбду как параметр public static String transform(Transformer fn, String param) return fn.apply(param); > public static void main(String[] args) var result = LambdaDemo.transform((input) -> input.toUpperCase(), "hello"); System.out.println(result); // Outputs: HELLO > >
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Что такое функциональный интерфейс java
На этом шаге мы рассмотрим функциональные интерфейсы
Ранее мы говорили об лямбда-выражениях. Но как мы знаем, у каждого результата выражения есть тип. Следовательно, у лямбд тоже должен быть тип. Все дело в том, что в Java любому лямбда-выражению соответствует интерфейс. Такие интерфейсы всегда содержат только один абстрактный метод. Но они могут содержать сколько угодно методов с реализацией по умолчанию (помеченные ключевым словом default). Также они помечены специальной аннотацией @FunctionalInterface. Такие интерфейсы носят название функциональные интерфейсы. В Java все стандартные функциональные интерфейсы лежат в пакете java.util.function. В приведенной ниже таблице приведены наиболее часто используемые интерфейсы.