正如其他人所说,功能接口是公开一种方法的接口。它可能有多个方法,但是其他所有方法必须具有默认实现。之所以称为“功能接口”,是因为它有效地充当了功能。由于您可以将接口作为参数传递,这意味着函数现在就像函数式编程语言一样,是“一等公民”。这有很多好处,使用Stream API时,您会看到很多好处。当然,lambda表达式是它们的主要明显用法。
我在Java 8中遇到了一个新术语:“功能接口”。在使用lambda expressions时,我只能找到它的一种用法。
Java 8提供了一些内置的功能接口,如果我们想定义任何功能接口,则可以使用@FunctionalInterface
批注。它将允许我们在接口中仅声明一个方法。
例如:
@FunctionalInterface
interface MathOperation {
int operation(int a, int b);
}
除了仅使用lambda表达式之外,它在Java 8中还有多大用处?
(here问题与我问的问题不同。它问的是为什么在使用lambda表达式时我们需要功能接口。我的问题是:为什么功能接口除了lambda表达式以外还有其他用途?]
@FunctionalInterface
批注对于检查代码的编译时间很有用。除了static
,default
和用于覆盖Object
中@FunctionalInterface
中的方法或用作功能接口的任何其他接口的抽象方法之外,您不能使用多个方法。
但是您可以使用不带此批注的lambda,也可以覆盖不带@Override
批注的方法。
来自文档
功能接口只有一种抽象方法。由于默认方法有一个实现,它们不是抽象的。如果一个接口声明一个抽象方法,该方法重写以下方法的公共方法之一java.lang.Object,这也不计入接口的抽象方法的数量,因为该接口的任何实现都会从java.lang.Object或其他地方获得实现
此可以使用在lambda表达式中:
public interface Foo {
public void doSomething();
}
此无法使用在lambda表达式中:
public interface Foo {
public void doSomething();
public void doSomethingElse();
}
但是这会导致编译错误:
@FunctionalInterface
public interface Foo {
public void doSomething();
public void doSomethingElse();
}
无效的'@FunctionalInterface'注释; Foo不是功能界面
功能接口:
documentation实际上在目的之间有所不同
一种说明性注释类型,用于指示接口类型声明旨在作为Java语言规范定义的功能接口。
和用例
请注意,可以使用lambda表达式,方法引用或构造函数引用来创建功能接口的实例。
其用语通常不排除其他用例。由于主要目的是指示功能接口,所以您的实际问题归结为“是否还有其他用例功能接口除了lambda表达式和方法/构造函数引用?”] >
由于功能接口
是Java语言规范定义的Java语言构造,因此只有该规范才能回答该问题:JLS §9.8. Functional Interfaces:
…
除了通过声明和实例化类来创建接口实例的常规过程(第15.9节)之外,还可以使用方法引用表达式和lambda表达式(第15.13节,第15.27节)创建功能接口的实例。
因此Java语言规范没有另外说明,该部分提到的唯一用例是使用方法引用表达式和lambda表达式创建接口实例。 (这包括构造函数引用,因为它们在规范中被称为方法引用表达式的一种形式。)>
所以一句话,不,在Java 8中没有其他用例。
正如其他人所说,功能接口是公开一种方法的接口。它可能有多个方法,但是其他所有方法必须具有默认实现。之所以称为“功能接口”,是因为它有效地充当了功能。由于您可以将接口作为参数传递,这意味着函数现在就像函数式编程语言一样,是“一等公民”。这有很多好处,使用Stream API时,您会看到很多好处。当然,lambda表达式是它们的主要明显用法。
完全没有。 Lambda表达式是该注释的唯一点。
lambda表达式可以分配给功能接口类型,但是方法引用和匿名类也可以分配。
关于java.util.function
中特定功能接口的一件好事是,由于它们包含的方便的默认方法,它们可以组成新的功能(例如Function.andThen
和Function.compose
,Predicate.and
等)。
仅具有一种抽象方法的接口称为功能接口。并非必须使用@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一起发布的新注释,它为lambda表达式提供了目标类型,并且用于代码的编译时检查。
当您想使用它时:
1-您的接口必须
具有多个抽象方法,否则将给出编译错误。1-您的接口应该是纯接口,这意味着功能接口旨在由无状态类实现,纯接口的示例是Comparator
接口,因为它不依赖于实现者状态,在这种情况下否
java.util.function
程序包包含各种通用功能接口,例如Predicate
,Consumer
,Function
和Supplier
。
也请注意,您可以使用不带此批注的lambda。
您可以在Java 8中使用lambda
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的更多信息,>
[除了其他答案,我认为“为什么不直接使用lambda表达式而不使用功能接口”的主要原因可能与面向对象的Java语言的性质有关。
Lambda表达式的主要属性是:1.它们可以传递2.可以在将来的特定时间(几次)执行。现在,为了以语言支持此功能,其他一些语言仅处理此问题。
例如,在Java Script中,一个函数(匿名函数或Function文字)可以作为一个对象来寻址。因此,您可以简单地创建它们,也可以将它们分配给变量等等。例如:
var myFunction = function (...) { ...; } alert(myFunction(...));
或通过ES6,您可以使用箭头功能。
const myFunction = ... => ...
到目前为止,Java语言设计者尚未接受通过这些方式(功能编程技术)来处理所提到的功能。他们认为Java语言是面向对象的,因此他们应该通过面向对象的技术解决此问题。他们不想错过Java语言的简单性和一致性。
因此,它们使用接口,因为当只需要一个方法(我的意思是功能接口)的接口的对象需要用lambda表达式替换时。如:
ActionListener listener = event -> ...;
功能接口:
- 在Java 8中引入]
- 包含“单个抽象”方法的接口。
示例1:
interface CalcArea { // --functional interface double calcArea(double rad); }
示例2:
interface CalcGeometry { // --functional interface double calcArea(double rad); default double calcPeri(double rad) { return 0.0; } }
示例3:
interface CalcGeometry { // -- not functional interface double calcArea(double rad); double calcPeri(double rad); }
Java8注释-
@FunctionalInterface
功能接口的应用:
要学习功能接口,首先要学习接口中的默认方法,学习功能接口后,您将很容易理解方法参考和lambda表达式
正如其他人所说,功能接口是公开一种方法的接口。它可能有多个方法,但是其他所有方法必须具有默认实现。之所以称为“功能接口”,是因为它有效地充当了功能。由于您可以将接口作为参数传递,这意味着函数现在就像函数式编程语言一样,是“一等公民”。这有很多好处,使用Stream API时,您会看到很多好处。当然,lambda表达式是它们的主要明显用法。
完全没有。 Lambda表达式是该注释的唯一点。
lambda表达式可以分配给功能接口类型,但是方法引用和匿名类也可以分配。
仅具有一种抽象方法的接口称为功能接口。并非必须使用@FunctionalInterface,但最好的做法是将其与功能接口一起使用,以避免意外添加其他方法。如果使用@FunctionalInterface注释对接口进行注释,并且我们尝试使用多个抽象方法,则它将引发编译器错误。
[@FunctionalInterface
是随Java 8一起发布的新注释,它为lambda表达式提供了目标类型,并且用于代码的编译时检查。
您可以在Java 8中使用lambda
[除了其他答案,我认为“为什么不直接使用lambda表达式而不使用功能接口”的主要原因可能与面向对象的Java语言的性质有关。
Lambda表达式的主要属性是:1.它们可以传递2.可以在将来的特定时间(几次)执行。现在,为了以语言支持此功能,其他一些语言仅处理此问题。