java8新特性- 函数式接口(Functional interfaces)

Posted 静宁微服务

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8新特性- 函数式接口(Functional interfaces)相关的知识,希望对你有一定的参考价值。

 


以上图片来自 Brian Goetz 的 State of Lambda一文,原文链接如下: http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html 

我们把这些只拥有一个方法的接口称为 函数式接口。(之前它们被称为 SAM类型,即 单抽象方法类型(SingleAbstract Method))

 

我们不需要额外的工作来声明一个接口是否是函数式接口:编译器会根据接口的结构自行判断(判断过程并非简单的对接口方法计数:一个接口可能冗余的定义了一个 Object 已经提供的方法,比如 toString(),或者定义了静态方法或默认方法,这些都不属于函数式接口方法的范畴)。不过API作者们可以通过 @FunctionalInterface注解来显式指定一个接口是函数式接口(以此避免无意中声明了一个符合函数式标准的接口),加上这个注解之后,编译器就会验证该接口是否满足函数式接口的要求。(个人建议,在开发的过程中,主动加上,以提高编译器的效率,CI也会报告此错误)


实现函数式类型的另一种方式是引入一个全新的 结构化 函数类型,我们也称其为“箭头”类型。(前端同学对javascript的ES6熟知的话,应该很了解箭头函数)例如,一个接收 String 和 Object 并返回 int 的函数类型可以被表示为 (String, Object) -> int。因为以下原因,我们将其否定了。


它会为Java类型系统引入额外的复杂度,并带来 结构类型(Structural Type) 和 指名类型(Nominal Type) 的混用。(Java 几乎全部使用指名类型)


它会导致类库风格的分歧——一些类库会继续使用回调接口,而另一些类库会使用结构化函数类型。


它的语法会变得十分笨拙,尤其在包含受检异常(checked exception)之后。


每个函数类型很难拥有其运行时表示,这意味着开发者会受到 类型模糊(erasure)的困扰和局限。比如说,我们无法对方法 m(T->U) 和 m(X->Y) 进行重载(Overload)。

基于以上理由,所以我们选择了“使用已知类型”这条路——因为现有的类库大量使用了函数式接口。


例如下面是 Java SE 7 中已经存在的函数式接口:


java.lang.Runnable

java.util.concurrent.Callable

java.security.PrivilegedAction

java.util.Comparator

java.io.FileFilter

java.beans.PropertyChangeListener 


除此之外,Java SE 8中增加了一个新的包:java.util.function,它里面包含了常用的函数式接口,例如:


Predicate<T>——接收 T 并返回 boolean

Consumer<T>——接收 T,不返回值

Function<T, R>——接收 T,返回 R

Supplier<T>——提供 T 对象(例如工厂),不接收值

UnaryOperator<T>——接收 T 对象,返回 T

BinaryOperator<T>——接收两个 T,返回 T


除了上面的这些基本的函数式接口,我们还提供了一些针对原始类型(Primitive type)的特化(Specialization)函数式接口,例如 IntSupplier 和 LongBinaryOperator。(我们只为 intlong 和 double 提供了特化函数式接口,如果需要使用其它原始类型则需要进行类型转换)同样的我们也提供了一些针对多个参数的函数式接口,例如 BiFunction<T, U, R>,它接收 T 对象和 U 对象,返回 R 对象。


总之,什么是函数式接口; 在java中,把这些只拥有一个方法的接口称为 函数式接口。定义就是这么简单,记住了吗?在心里默念三遍。。。

具体的使用:声明一个接口,加上注解@FunctionalInterface。

 其实绝大部分的时候,我们是在使用JDK提供的已知接口,因为这些接口已经提供了开箱即用的功能。


@FunctionalInterface

public interface Runnable {

    public abstract void run();

}



更多的时候,希望大家去阅读官网的英文资料,会收获更多。明天又是美好的一天,加油哦~



以上是关于java8新特性- 函数式接口(Functional interfaces)的主要内容,如果未能解决你的问题,请参考以下文章

JAVA8新特性---函数式接口

JAVA8新特性---函数式接口

Java8新特性之函数式接口

Java8新特性之函数式接口

Java8 新特性----函数式接口,以及和Lambda表达式的关系

java8新特性——函数式接口,方法,构造器,数组引用