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
。(我们只为 int
、long
和 double
提供了特化函数式接口,如果需要使用其它原始类型则需要进行类型转换)同样的我们也提供了一些针对多个参数的函数式接口,例如 BiFunction<T, U, R>
,它接收 T
对象和 U
对象,返回 R
对象。
总之,什么是函数式接口; 在java中,把这些只拥有一个方法的接口称为 函数式接口。定义就是这么简单,记住了吗?在心里默念三遍。。。
具体的使用:声明一个接口,加上注解@FunctionalInterface。
其实绝大部分的时候,我们是在使用JDK提供的已知接口,因为这些接口已经提供了开箱即用的功能。
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
更多的时候,希望大家去阅读官网的英文资料,会收获更多。明天又是美好的一天,加油哦~
以上是关于java8新特性- 函数式接口(Functional interfaces)的主要内容,如果未能解决你的问题,请参考以下文章