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
注释对编译时间检查代码很有用。 除了static
, default
和抽象方法之外,不能有多个方法来覆盖@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.andThen
和Function.compose
, Predicate.and
等)。
正如其他人所说,function性接口是一种暴露一种方法的接口。 它可能有多个方法,但其他方法都必须有一个默认的实现。 它被称为“function接口”的原因是因为它有效地作为一个function。 既然你可以将接口作为parameter passing,那么就意味着函数现在就像函数式编程语言一样是“一等公民”。 这有很多好处,使用Stream API时你会看到很多好处。 当然,lambdaexpression式是它们的主要用途。