函数式接口
虽然Lambda表达式可以实现匿名内部类的功能,但在使用时却有一个局限,即接口中有且只有一个抽象方法时才能使用Lamdba表达式代替匿名内部类。这是因为Lamdba表达式是基于函数式接口实现的,所谓函数式接口是指有且仅有一个抽象方法的接口,Lambda表达式就是Java中函数式编程的体现,只有确保接口中有且仅有一个抽象方法,Lambda表达式才能顺利地推导出所实现的这个接口中的方法。
在JDK 8中,专门为函数式接口引入了一个@FunctionalInterface注解,该注解只是显示的标注了接口是一个函数式接口,并强制编辑器进行更严格的检查,确保该接口是函数式接口,如果不是函数式接口,那么编译器就会报错,而对程序运行并没有实质上的影响,
接下来通过一个案例来演示函数式接口的定义与使用,如文件1所示。
文件1 Example23.java
1 // 定义无参、无返回值的函数式接口
2 @FunctionalInterface
3 interface Animal {
4 void shout();
5 }
6 // 定义有参、有返回值的函数式接口
7 interface Calculate {
8 int sum(int a, int b);
9 }
10 public class Example23 {
11 public static void main(String[] args) {
12 // 分别两个函数式接口进行测试
13 animalShout(() -> System.out.println("无参、无返回值的函数式接口调用"));
14 showSum(10, 20, (x, y) -> x + y);
15 }
16 // 创建一个动物叫的方法,并传入接口对象Animal作为参数
17 private static void animalShout(Animal animal) {
18 animal.shout();
19 }
20 // 创建一个求和的方法,并传入两个int类型以及接口Calculate类型的参数
21 private static void showSum(int x, int y, Calculate calculate) {
22 System.out.println(x + "+" + y + "的和为:" + calculate.sum(x, y));
23 }
24 }
运行结果如图1所示。
图1 运行结果
文件1中,先定义了两个函数式接口Animal和Calculate,然后在测试类中分别编写了两个静态方法,并将这两个函数式接口以参数的形式传入,最后在main()方法中分别调用这两个静态方法,并将所需要的函数式接口参数以Lambda表达式的形式传入。从图1可以看出,程序中函数式接口的定义和使用完全正确。