什么是函数式接口(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方法,那么在类的接口上包含这些默认方法是没有意义的,它们也从来不会被编译。)

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐