Что использование функционального интерфейса в Java 8?



я наткнулся на новый термин под названием Функционального Интерфейса в Java 8.



я смог найти только одно использование этого интерфейса во время работы с лямбда-выражения.



в Java 8 предоставляет некоторые встроенные функциональные интерфейсы и если мы хотим определить любой функциональный интерфейс, то мы можем использовать @FunctionalInterface Примечание. Это позволит нам объявить только один метод в интерфейсе.



для пример:



@FunctionalInterface
interface MathOperation {
int operation(int a, int b);
}


насколько это полезно в Java 8, кроме просто работы с лямбда-выражения?



вопрос здесь отличается от того, который я задал. Он спрашивает, зачем нам нужно Функционального Интерфейса при работе с лямбда-выражение. Мой вопрос: почему с помощью Функционального Интерфейса кроме непосредственно с лямбда-выражения?

973   10  

10 ответов:

@FunctionalInterface аннотация полезна для проверки времени компиляции вашего кода. Вы не можете иметь более одного метода, кроме static,default и абстрактные методы, которые переопределяют методы в Object в своем @FunctionalInterface или любой другой интерфейс, используемый в качестве функционального интерфейса.

но вы можете использовать лямбды без этой аннотации, а также переопределять методы без @Override Примечание.

идее

функциональный интерфейс в точности один абстрактный метод. Поскольку по умолчанию методы имеют реализацию, они не абстрактны. Если интерфейс объявляет абстрактный метод, переопределяющий один из общедоступных методов Ява.ленг.Объект, который также не учитывается в интерфейсе абстрактный метод подсчета, так как любая реализация интерфейса будет есть реализация от java.ленг.Объект или в другом месте

этой можно использовать в лямбда-выражение:

public interface Foo {
  public void doSomething();
}

этот нельзя использовать в лямбда-выражение:

public interface Foo {
  public void doSomething();
  public void doSomethingElse();
}

но это даст ошибка компиляции:

@FunctionalInterface
public interface Foo {
  public void doSomething();
  public void doSomethingElse();
}

недопустимая аннотация' @FunctionalInterface'; Foo не является функциональным интерфейс

функциональные интерфейсы есть одна функциональность, чтобы показать. Например, для сравнения используется сопоставимый интерфейс с одним методом "compareTo". Java 8 определила множество функциональных интерфейсов широко используется в лямбда-выражениях.

там введена аннотация -@FunctionalInterface который может использоваться для ошибок уровня компилятора, когда интерфейс, который вы аннотировали, не является допустимым функционалом Взаимодействие.

@FunctionalInterface
 interface MathOperation {
      int operation(int a, int b);
 }

давайте попробуем добавить еще один абстрактный метод:

@FunctionalInterface
 interface MathOperation {
      int operation(int a, int b);
      int operationMultiply(int a, int b);
 }

выше приведет к ошибке компилятора, как показано ниже:

Unexpected @FunctionalInterface annotation
@FunctionalInterface ^ MathOperation is not a functional interface
multiple non-overriding abstract methods found in interface MathOperation

функциональный интерфейс действителен, даже если @FunctionalInterface аннотация будет опущена. Это только для информирования компилятора о применении одного абстрактного метода внутри интерфейса.

 interface MathOperation {
      int operation(int a, int b);
 }

концептуально, функциональный интерфейс имеет ровно один абстрактный метод. Поскольку методы по умолчанию имеют реализация, они не абстрактны. Поскольку методы по умолчанию не являются абстрактными, вы свободно добавлять методы по умолчанию в свой функциональный интерфейс столько, сколько вам нравится.

ниже приведен допустимый функциональный интерфейс:

@FunctionalInterface
 interface MathOperation {
      int operation(int a, int b);
      default void doSomeMathOperation(){
       //Method body
      }
 }

если интерфейс объявляет абстрактный метод, переопределяющий один из общедоступных методов java.ленг.Объект, который также не считается к абстрактному методу интерфейса count, так как любая реализация интерфейса будет есть реализация от java.ленг.Объект или в другом месте.

например, Ниже приведен допустимый функциональный интерфейс, хотя он объявил два абстрактных метода. Зачем? Потому что один из этих абстрактных методов "equals ()", который имеет сигнатуру, равную публичному методу в классе объектов.

@FunctionalInterface
 interface MathOperation {
      int operation(int a, int b);
      @Override
      public String toString();  //Overridden from Object class
      @Override
      public boolean equals(Object obj); //Overridden from Object class
 }

в то время как целевое использование функциональные интерфейсы на лямбда-выражения, ссылки на методы и ссылки на конструктор, они все еще могут использоваться, как и любой интерфейс, с анонимными классами, реализованными классами или созданными заводскими методами.

The документация действительно делает разницу между целью

информативный тип аннотации, используемый для указания того, что объявление типа интерфейса должно быть функционального интерфейса как определено спецификацией языка Java.

и в случае

обратите внимание, что экземпляры функциональных интерфейсов могут быть созданы с помощью лямбда-выражений, ссылок на методы или конструктора ссылки на литературу.

чья формулировка не исключает других случаев использования в целом. Поскольку основная цель состоит в том, чтобы указать функционального интерфейса, ваш фактический вопрос сводится к " есть ли другие варианты использования для функциональные интерфейсы кроме лямбда-выражений и ссылок на метод/конструктор?"

с функционального интерфейса - это конструкция языка Java, определенная спецификацией языка Java, только эта спецификация может ответить на этот вопрос:

JLS §9.8. Функциональные Интерфейсы:

...

в дополнение к обычному процессу создания экземпляра интерфейса путем объявления и создания экземпляра класса (§15.9), экземпляры функциональных интерфейсов могут быть созданы с помощью ссылочных выражений метода и лямбда-выражений (§15.13, §15.27).

таким образом, спецификация языка Java не говорит иначе, единственный случай использования, упомянутый в этом разделе, - это создание экземпляров интерфейса с ссылочными выражениями метода и лямбда-выражениями. (Это включает ссылки на конструктор, поскольку они отмечены как одна из форм выражения ссылки на метод в спецификации).

Так что в одном предложении, нет, нет другого варианта использования для него в Java 8.

вовсе нет. Лямбда-выражения являются единственной точкой этой аннотации.

лямбда-выражение может быть назначено функциональному типу интерфейса, но также могут быть назначены ссылки на методы и анонимные классы.

одна хорошая вещь о конкретных функциональных интерфейсов в java.util.function Это то, что они могут быть составлены для создания новых функций (например,Function.andThen и Function.compose,Predicate.and и т. д.) из-за удобных методов по умолчанию, которые они содержат.

Как уже говорили другие, функциональный интерфейс-это интерфейс, который предоставляет один метод. Он может иметь несколько методов, но все остальные должны иметь реализацию по умолчанию. Причина, по которой он называется "функциональным интерфейсом", заключается в том, что он эффективно действует как функция. Поскольку вы можете пройти интерфейсы в качестве параметров, это означает, что функции "первого сорта", как в функциональных языках программирования. Это имеет много преимуществ, и вы увидите их довольно много при использовании Stream API. Конечно, лямбда-выражения являются основным очевидным использованием для них.

интерфейс только с одним абстрактным методом называется функциональным интерфейсом. Не обязательно использовать @FunctionalInterface, но лучше всего использовать его с функциональными интерфейсами, чтобы избежать случайного добавления дополнительных методов. Если интерфейс аннотирован аннотацией @FunctionalInterface, и мы пытаемся иметь более одного абстрактного метода, он выдает ошибку компилятора.

package com.akhi;
    @FunctionalInterface
    public interface FucnctionalDemo {

      void letsDoSomething();
      //void letsGo();      //invalid because another abstract method does not allow
      public String toString();    // valid because toString from Object 
      public boolean equals(Object o); //valid

      public static int sum(int a,int b)   // valid because method static
        {   
            return a+b;
        }
        public default int sub(int a,int b)   //valid because method default
        {
            return a-b;
        }
    }

@FunctionalInterface Это новая аннотация, выпущенная с Java 8 и предоставляющая целевые типы для лямбда-выражений, и она используется при проверке времени компиляции вашего кода.

когда вы хотите использовать его :

1 - интерфейс не должен есть несколько абстрактных методов, в противном случае ошибка компиляции будет дана.

1 - интерфейс должны быть чистым, что означает, что функциональный интерфейс предназначен для реализации без состояния классы, exmple из чистого is Comparator интерфейс, потому что его не зависит от состояния исполнителей, в этом случае нет ошибка компиляции будет дана, но во многих случаях вы не сможете использовать лямбда с такого рода интерфейсами

The java.util.function пакет содержит различные функциональные интерфейсы общего назначения, такие как Predicate,Consumer,Function и Supplier.

Также обратите внимание, что вы можете использовать лямбда-выражения без этой аннотации.

помимо других ответов, я думаю, что основная причина "почему использование функционального интерфейса, отличного от прямого использования лямбда-выражений", может быть связана с природой языка Java, который является объектно-ориентированным.

основными атрибутами лямбда-выражений являются: 1. Они могут быть переданы около 2. и они могут быть выполнены в будущем в определенное время (несколько раз). Теперь, чтобы поддержать эту функцию в языках, некоторые другие языки имеют дело просто с этим вопросом.

например в Java Скрипт, функция (анонимная функция или литералы функций) могут быть адресованы как объект. Таким образом, вы можете создать их просто, а также они могут быть присвоены переменным и так далее. Например:

var myFunction = function (...) {
    ...;
}
alert(myFunction(...));

или через ES6, вы можете использовать функцию стрелки.

const myFunction = ... => ...

до сих пор разработчики языка Java не приняли для обработки упомянутых функций с помощью этого способа (методы функционального программирования). Они считают, что язык Java является объектно-ориентированным и, следовательно, они должны решить эту проблему с помощью объектно-ориентированных методов. Они не хотят пропустить простоту и согласованность языка Java.

ActionListener listener = event -> ...;

вы можете использовать лямбда-выражения в Java 8

  public static void main(String[] args) {
    tentimes(inputPrm -> System.out.println(inputPrm));
    //tentimes(System.out::println);  // You can also replace lambda with static method reference
    }

    public static void tentimes(Consumer myFunction){
      for(int i = 0; i < 10; i++)
        myFunction.accept("hello");
    }

для получения дополнительной информации о Java Lambdas и FunctionalInterfaces

Comments

    Ничего не найдено.