Java8——函数式接口

函数式接口也称 SAM 接口,即 Single Abstract Method interfaces,有且只有一个抽象方法,但可以有多个非抽象方法的接口。

为了让现有的功能和lambda表达式友好兼容,于是就有了函数接口这个概念。函数式接口是只包含一个抽象方法声明的接口。像这样地,函数接口可以隐式地转换成lambda表达式。

java.lang.Runnable 和java.util.concurrent.Callable是函数接口两个最好的例子。在 Runnable 接口中只声明了一个方法 void run(),我们使用匿名内部类来实例化函数式接口的对象,有了 Lambda 表达式,这一方式可以得到简化。看一下Java 8之前的runnable实现方法,需要4行代码,而使用lambda表达式只需要一行代码。

// Java 8之前:

new Thread(new Runnable() {

    @Override

    public void run() {

    System.out.println("Before Java8, too much code for too little to do");

    }

}).start();

//Java 8方式:

new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();

但是在实践中,函数接口是非常脆弱的,只要有人在接口里添加多一个方法,那么这个接口就不是函数接口了,就会导致编译失败。Java 8提供了一个特殊的注解@FunctionalInterface来克服上面提到的脆弱性并且显示地表明函数接口的目的(java里所有现存的接口都已经加上了@FunctionalInterface)。让我们看看一个简单的函数接口定义:

@FunctionalInterface

public interface Functional {

void method();

}

我们要记住默认的方法和静态方法不会违反函数接口的约定,例子如下:

@FunctionalInterface

public interface FunctionalDefaultMethods {

void method();

default void defaultMethod() {

}

}

在 java 8 中专门有一个包放函数式接口java.util.function,该包下的所有接口都有 @FunctionalInterface 注解,提供函数式编程。

在其他包中也有函数式接口,其中一些没有@FunctionalInterface 注解,但是只要符合函数式接口的定义就是函数式接口,与是否有@FunctionalInterface注解无关,注解只是在编译时起到强制规范定义的作用。其在 Lambda 表达式中有广泛的应用。

参考:

Java 8 特性 – 终极手册 | 并发编程网 – ifeve.com

JAVA8 十大新特性详解_java8新特性-CSDN博客

Java8 新特性实战 | JavaGuide(Java面试 + 学习指南)