Java 8之FunctionalInterface深度解析(一)

引言: 虽然Java拥有数量庞大的开发者群体,但是其亦不能免俗,不能不追随业界流行的趋势,逐步加入新的流行元素。 在JDK 8中加入针对函数式编程的支持,而@Functionalinterface便是其中之一,本文将深度分析Functional interface的应用与使用经验。

函数式编程

这个话题有点偏学术,但是不妨碍一起来了解一下。在面向对象编程之前,是面向过程的结构化分析和编程。在面向对象技术大行其道的若干年之后,函数式编程一种新的方式日渐兴起,为越来越多的开发者所接纳,究其本质,“函数式编程”是一种编程的范式和编程的方法论(programming paradigm),它属于结构化编程的一种,主要的思想是把运算的过程尽量通过一组嵌套的函数来实现。
听了这么多晦涩的术语之后,大家不禁会问:面向对象这么强大的东东,怎么还会有函数式的市场? 其实问题的症结点就在于函数式编程在当今的编程领域,其有何种价值?基于笔者的思考和观察分析,函数式编程本质的提升是在于用更少的代码实现了更多的功能,可以基于表达式就可以解决单独定义的方法需要解决的问题,且没有什么副作用,大大提升了开发者的开发效率。
下面来近距离观察一下函数式编程的几个特点:

  • 函数可以作为变量、参数、返回值和数据类型。
  • 基于表达式来替代方法的调用
  • 函数无状态,可以并发和独立使用
  • 函数无副作用,不会修改外部的变量
  • 函数结果确定性;同样的输入,必然会有同样的结果。

函数式编程的优点:

  • 代码简洁,开发效率高
  • 接近自然语言,易于理解
  • 由于函数的特性,易于调试和使用
  • 易于并发使用
  • 脚本语言的特性,易于升级部署

FunctionalInterface

在JDK 8中引入了FunctionalInterface接口,其源代码定义如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

从其接口定义来看,其在运行时使用,没有具体的方法,为标识(Markable)接口。
关于接口的具体功能和使用,先看权威的官方说明吧,由于官方说明比较长,这里截取其中的关键信息如下,关于功能描述:

An informative annotation type used to indicate that an interface type declaration is intended to be a <i>functional interface</i> as defined by the Java Language Specification.

翻译过来就是其用来标识接口为函数接口。
那关于注意事项主要有以下几点:

  • 唯一的抽象方法,有且仅有一个
    Conceptually, a functional interface has exactly one abstract method.
  • 可用于lamba类型的使用方式
    Note that instances of functional interfaces can be created with lambda expressions, method references, or constructor references.
  • 不能被覆盖之后,再声明为抽象方法,则不算抽象方法。例如接口实现了Object中的方法。

    If an interface declares an abstract method overriding one of the public methods of {@code java.lang.Object}, that also does <em>not</em> count toward the interface's abstract method count since any implementation of the interface will have an implementation from {@code java.lang.Object} or elsewhere.
  • 加上标注,则会触发JavaCompiler的检查。对于符合函数接口的接口,加不加都无关紧要,但是加上则会提供一层编译检查的保障。如果不符合,则会报错。

    However, the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.

    基于@FunctionalInterface的官方说明,做了一番解释,希望可以帮助大家更好地理解其应用。

简单示例

定义一个Hello的接口:

@FunctionalInterface
public interface Hello {
    String msg(String info);
}

调用执行示例:

Hello hello = param -> param + "world!";
System.out.println("test functional:" + hello.msg("hello,"));

则输出为:

test functional:hello,world!

从上述的代码中可以发现,核心点在于->前后的内容,基于->声明了一个功能函数FunctionalInterface,这可以在代码中直接进行调用。
本质上是将函数的实现直接转换为了一个声明语句的定义,极大简化了原有的实现方式。又有的实现方式是什么呢,下面来看一下:

  Hello hello2 = new Hello() {
            @Override
            public String msg(String info) {
                return info + ",world";
            }
        };

相比来看,是否变得简单了一些?

总结

在本节中,介绍了函数式编程的概念和基本特征,并针对@FunctionalInterface的功能和使用做了介绍,最后通过一个简要的示例来展示其基本用法。
接下来还将针对其高级用法以及注意事项进行分析,稍后待续。

猜你喜欢

转载自blog.csdn.net/blueheart20/article/details/80403735