@FunctionalInterface
·
什么是函数式接口(Functional Interface)
其实之前在讲Lambda表达式的时候提到过,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法。
这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。
函数式接口用途
它们主要用在Lambda表达式和方法引用(实际上也可认为是Lambda表达式)上。
如定义了一个函数式接口如下:
@FunctionalInterface
public interface Person {
void sayHello(String msg);
}
那么就可以使用Lambda表达式来表示该接口的一个实现(注:JAVA 8 之前一般是用匿名类实现的):
Person personSay = message -> System.out.println("Hello " + message);
关于@FunctionalInterface注解
Java 8为函数式接口引入了一个新注解@FunctionalInterface,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。
正确的例子:
错误的列子:
@FunctionalInterface标记在接口上,“函数式接口”是指仅仅只包含一个 抽象方法*的接口。
在编译期间检查。
@FunctionalInterface 仅对抽象方法检查。
- 1、该注解只能标记在"有且仅有一个抽象方法"的接口上。
- 2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。
- 3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么 也不算抽象方法。
注:该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
为什么不能用默认方法来重载equals,hashCode和toString?
接口不能提供对Object类的任何方法的默认实现。从接口里不能提供对equals,hashCode或toString的默认实现。因为若可以会很难确定什么时候该调用接口默认的方法。
如果一个类实现了一个方法,那总是优先于默认的实现的。一旦所有接口的实例都是Object的子类,所有接口实例都已经有对equals/hashCode/toString等方法默认实现。因此,一个在接口上的这些默认方法都是没用的,它也不会被编译。(简单地讲,每一个java类都是Object的子类,也都继承了它类中的equals/hashCode/toString方法,那么在类的接口上包含这些默认方法是没有意义的,它们也从来不会被编译。)
更多推荐
已为社区贡献2条内容
所有评论(0)