Java8投入大量精力来思考如何使现有的函数更加友好的支持Lambda表达式,最终引入了函数式接口的概念。函数式接口本质上是一个仅有一个抽象方法的普通接口。函数式接口能够被隐式地转换为Lambda表达式。例如在上一篇文章的最后一个示例,ActionListener监听接口只有一个方法,就可以使用Lambda表达式进行简化。
函数式接口在实际使用过程中很容易出错,例如某个人在接口定义中又增加了另一个方法,则该接口不再是函数式接口,此时将该接口转化为Lambda表达式会失败。为了克服函数式接口的脆弱性,并且能够明确声明接口是作为函数式接口的意图,Java8中增加了一个注解@FunctionalInterface来定于函数式接口
@FunctionalInterface
public interface 接口名{
//只有一个抽象方法
}
使用@FunctionalInterface修饰的接口必须是函数式接口,该接口中只能声明一个抽象方法,如果声明多个抽象方法则会报错。但默认方法和静态方法不属于抽象方法,因此在函数式接口中也可以定义默认方法和静态方法
FIConverter.java
//定义函数式接口
@FunctionalInterface
public interface FIConverter<F,T>{
T convert(F from);
}
上述代码使用@FunctionalInterface注解对FIConverter接口进行修饰,用于指明该接口是函数式接口。在FIConverter函数式接口中声明了一个convert()抽象方法,该方法是基于泛型的,以便实现不同数据类型之间的转换。
FunctionalInterfaceDemo.java
public class FunctionalInterfaceDemo {
public static void main(String[] args) {
//传统方法实现函数式接口中的抽象方法
FIConverter<String,Integer>converter1 = new FIConverter<String, Integer>() {
@Override
public Integer convert(String from) {
return Integer.valueOf(from);
}
};
//调用convert()方法,将字符串转换为整数
Integer a = converter1.convert("88");
System.out.println(a);
//Lambda表达式方式实现函数式接口中的抽象方法
FIConverter<String,Integer>converter2 = (from) -> Integer.valueOf(from);
Integer b = converter2.convert("123");
System.out.println(b);
}
}
上述代码分别使用传统方式以及Lambda表达式来实现函数式接口中的抽象方法,使用Lambda表达式后语句更加简洁。
Lambda表达式只能为函数式接口创建对象,即Lambda表达式只能实现具有一个抽象方法的接口,且该接口必须是由@FunctionalInterface注解修饰的函数式接口