Java 8中的Functional Interface有什么用?

我在Java 8中遇到了一个名为“Functional Interface”的新术语。

在使用Lambdaexpression式时,我只能find这个接口的一个用法。

Java 8提供了一些内置的function接口,如果我们想要定义任何function接口,那么我们可以使用@FunctionalInterface注解。 它将允许在界面中声明唯一的方法。

例如:

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

它在Java 8中有多有用(与使用Lambdaexpression式不同)?

这里的问题与我所问的不一样。 这是问为什么我们需要function接口,同时使用Lambdaexpression式。 我的问题是使用除Lambdaexpression式以外的function接口。

@FunctionalInterface注释对编译时间检查代码很有用。 除了staticdefault和抽象方法之外,不能有多个方法来覆盖@FunctionalInterface中的Object中的方法或用作function接口的任何其他接口。

但是你可以使用没有这个注解的lambdaexpression式,也可以覆盖没有@Override注解的方法。

从文档

一个function界面恰好有一个抽象方法。 由于默认方法有一个实现,它们不是抽象的。 如果一个接口声明一个抽象方法覆盖java.lang.Object的一个公共方法,那么它也不会计入接口的抽象方法计数,因为接口的任何实现都会从java.lang.Object或其他地方

可以在lambdaexpression式中使用:

 public interface Foo { public void doSomething(); } 

不能在lambdaexpression式中使用:

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

但这会给编译错误

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

无效的“@FunctionalInterface”注释; Foo不是一个function界面

function接口有一个单一的function展示。 例如,使用单个方法“compareTo”的Comparable接口用于比较。 Java 8已经定义了许多在lambdaexpression式中广泛使用的函数接口。

引入了一个注释 – @FunctionalInterface ,当您注释的接口不是有效的function接口时,可用于编译器级错误。

 @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); } 

从概念上讲,一个function接口只有一个抽象方法。 由于默认方法有一个实现,它们不是抽象的。 由于默认的方法不是抽象的,你可以自由地添加默认方法到你的function界面尽可能多。

以下是有效的function界面:

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

如果一个接口声明一个抽象方法覆盖java.lang.Object的公共方法之一,那么也不会计入接口的抽象方法计数,因为接口的任何实现都将具有java.lang.Object或其他地方的实现。

例如,下面是一个有效的函数接口,即使它声明了两个抽象方法。 为什么? 因为这些抽象方法之一是“equals()”,它的签名等于Object类中的公共方法。

 @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 } 

尽pipeFunctional接口的用途是用于lambdaexpression式方法引用构造函数引用 ,但它们仍然可以像使用匿名类,由类实现或由工厂方法创build的接口一样使用。

文件确实是一个目的之间的差异

用来指示接口types声明是由Java语言规范定义的函数接口的信息注释types。

和用例

请注意,可以使用lambdaexpression式,方法引用或构造函数引用来创build函数接口的实例。

其措辞一般不排除其他用例。 由于主要目的是指示一个function接口 ,所以您的实际问题归结为 除了lambdaexpression式和方法/构造函数引用之外, 是否还有其他函数接口的用例

由于function接口是由Java语言规范定义的Java语言结构,因此只有该规范才能回答这个问题:

JLS§9.8。 function接口 :

除了通过声明和实例化一个类(第15.9节)创build接口实例的常用过程之外,还可以使用方法引用expression式和lambdaexpression式(第15.13节,第15.27节)创build函数接口的实例。

所以Java语言规范没有另外说明,这一节中提到的唯一用例是用方法引用expression式和lambdaexpression式创build接口实例。 (这包括构造函数引用,因为它们在说明中被称为方法引用expression式的一种forms)。

所以在一句话中,不,在Java 8中没有其他用例。

一点也不。 Lambdaexpression式是该注释的唯一一点。

可以将lambdaexpression式分配给function接口types,但方法引用和匿名类也可以。

关于java.util.function特定函数接口的一个java.util.function是,由于它们包含的方便的缺省方法,可以组合它们来创build新的函数(如Function.andThenFunction.composePredicate.and等)。

正如其他人所说,function性接口是一种暴露一种方法的接口。 它可能有多个方法,但其他方法都必须有一个默认的实现。 它被称为“function接口”的原因是因为它有效地作为一个function。 既然你可以将接口作为parameter passing,那么就意味着函数现在就像函数式编程语言一样是“一等公民”。 这有很多好处,使用Stream API时你会看到很多好处。 当然,lambdaexpression式是它们的主要用途。