请不要吐槽太多,我才刚刚开始翻译文章
函数式接口简介 - Java 8 中重新创建的概念
世界上的每个 Java 开发人员都至少使用过以下接口之一:java.lang.Runnable
、java.awt.event.ActionListener
、java.util.Comparator
、java.util.concurrent.Callable
。它们都有一个共同点,那就是它们都只有一种方法。JDK 中还有许多其他此类接口,以及 Java 开发人员创建的其他接口。这些接口也称为Single Abstract Method interfaces
(SAM 接口)。使用这些接口的最流行的方法之一是创建使用这些接口的匿名内部类,如下例所示:
public class AnonymousInnerClassTest {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("A thread created and running...");
}
}).start();
}
}
在 Java 8 中,重新创建了 SAM 概念,并将其称为函数式接口。它们可以使用 lambda 表达式、方法引用和引用构造函数来表示。创建了一个新的 @FunctionalInterface 注释,当您注释的接口在功能级别不起作用时,该注释用于在编译器级别引发错误。让我们看一下带有一个抽象方法的简单函数式接口:
@FunctionalInterface
public interface SimpleFunInterface {
public void doWork();
}
接口还可以声明类的抽象方法java.lang.Object
,但在这种情况下,接口也可以声明为函数式:
@FunctionalInterface
public interface SimpleFuncInterface {
public void doWork();
public String toString();
public Boolean equals(Object o);
}
一旦您向接口添加了另一个抽象方法,IDE 就会将其标记为错误,如图所示:
一个接口可以继承另一个接口;如果该接口继承自函数式接口并且不包含新的抽象方法,则该接口也是函数式接口。但是一个接口只能包含一个抽象方法和许多默认方法,并且它仍然被认为是函数式的。
@FunctionalInterface
public interface ComplexFunctionalInterface extends SimpleFuncInterface {
default public void doSomeWork() {
System.out.println("Doing some work in interface impl...");
}
default public void doSomeWork() {
System.out.println("Doing some other work in interface impl...");
}
}
上面的例子仍然是一个函数式接口。现在让我们看看如何使用 lambda 表达式来替换匿名内部类来实现函数式接口:
/*
*Implementation the interface by creating an
*anonymoous inner class versus using
*lambda expression.
*/
public class SimpleFunInterfaceTest {
public static void main(String[] args) {
carryOutWork(new SimpleFunInterface() {
@Override
public void doWork() {
System.out.println("Do work in SimpleFun impl...");
}
});
carryOutWork(() -> System.out.println("Do work in lambda exp impl..."));
}
public static void carryOutWork(SimpleFuncInterface sfi) {
sfi.work();
}
}
程序的结果如下:
Do work in SimpleFun impl...
Do work in lambda exp impl...
如果您使用的 IDE 支持 Java lambda 表达式语法(Netbeans 8 Nightly builds),那么您在使用匿名内部类时会得到提示: 这是对 Java 8 中函数式接口的概念以及如何实现它们的简要介绍使用 lambda 表达式。
GO TO FULL VERSION