JavaRush /Java блог /Random /Java functional interfaces
Алексей
32 уровень

Java functional interfaces

Статья из группы Random
Функциональный интерфейс в Java – это интерфейс, который содержит только 1 абстрактный метод. Основное назначение – использование в лямбда выражениях и method reference.
Java functional interfaces - 1
Наличие 1 абстрактного метода - это единственное условие, таким образом функциональный интерфейс может содержать так же default и static методы. К функциональному интерфейсу можно добавить аннотацию @FunctionalInterface. Это не обязательно, но при наличии данной аннотации код не скомпилируется, если будет больше или меньше, чем 1 абстрактный метод. Рекомендуется добавлять @FunctionalInterface. Это позволит использовать интерфейс в лямбда выражениях, не остерегаясь того, что кто-то добавит в интерфейс новый абстрактный метод и он перестанет быть функциональным. В Java есть встроенные функциональные интерфейсы, размещенные в пакете java.util.function. Не буду останавливаться на них подробно. Отмечу, что наиболее часто используются: Consumer<T>, Function<T,R>, Predicate<T>, Supplier<T>, UnaryOperator<T> и их 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<Integer> 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<T> {
   int compare(T o1, T o2);
   boolean equals(Object obj);
   // другие default или static методы
}
Будьте внимательны на собеседовании! Удачи!
Комментарии (3)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Денис Кайдунов Уровень 38
29 апреля 2022
Спасибо за статью, очень классно написано. Наконецто я это вкурил! СПАСИБО!
Anonymous #1190225 Уровень 40
30 апреля 2018
Не знать, что

@FunctionalInterface
может содержать методы класса Object совершенно нормально. Если на интервью вам говорят, что вы не знаете какой-то ерунды, подобной этой, то нормальным ответом является задать вопрос, как это можно использовать или как это знание может пригодиться при работе над реальным кодом. Знание не должно быть ради знания. Целью является написание полезного и качественного кода, используя инструменты, предлагаемые языком.