Java8 函数式接口@FunctionalInterface

FunctionalInterface 的注释

/**
 * 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.

用于指示接口的信息注释类型,类型声明是一个 函数接口
由Java语言规范定义。

Conceptually, a functional interface has exactly one abstract
 * method.  Since {@linkplain java.lang.reflect.Method#isDefault()
 * default methods} have an implementation, they are not abstract.  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.

从概念上讲,函数接口只有一个抽象方法。自{@linkplain java.lang.reflect.Method # isDefault ()默认方法}有一个实现,它们不是抽象的。如果一个接口声明了一个抽象方法来覆盖其中的一个
{@code java.lang的公共方法。对象},这也是
不是计数到接口的抽象方法计数因为接口的任何实现都会有一个
实现自{@code java.lang。对象}或其他地方。

Note that instances of functional interfaces can be created with
 * lambda expressions, method references, or constructor references.

函数式接口的实例可通过lamda表达式,函数的引用,构造函数 来创建

* <p>If a type is annotated with this annotation type, compilers are
 * required to generate an error message unless:
 *
 * <ul>
 * <li> The type is an interface type and not an annotation type, enum, or class.
 * <li> The annotated type satisfies the requirements of a functional interface.
 * </ul>
 *

如果一个声明类型添加了这种注释,接口除非满足以下两种情况会报错
1、这种类型是接口而不是注释类型 枚举类型或者类
2、这种声明类型符合函数接口的要求

 * <p>However, the compiler will treat any interface meeting the
 * definition of a functional interface as a functional interface
 * regardless of whether or not a {@code FunctionalInterface}
 * annotation is present on the interface declaration.

然而编译器将会把那些符合函数是定义的接口当做函数式接口,不论这个接口是否有@FunctionalInterface的注解

什么是函数式接口

所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法。

这种类型的接口也称为SAM接口,即Single Abstract Method interfaces

特点

接口有且仅有一个抽象方法
允许定义静态方法
允许定义默认方法
允许java.lang.Object中的public方法
该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错

总结

1、如果一个接口只有一个抽象方法,那么该接口是函数式接口
2、如果一个接口声明了@FunctionalInterface ,那么编译器就会按照函数式接口的定义来要求该接口
3、如果某个接口只有一个抽象方法,单我们并没有给该接口声明FunctionalInterface注解,那么编译器依旧会将该接口看做是函数式接口

函数式接口的实例可通过lamda表达式,函数的引用,构造函数 来创建

例子

// 正确的函数式接口
@FunctionalInterface
public interface TestInterface {
 
    // 抽象方法
    public void sub();
 
    // java.lang.Object中的public方法
    public boolean equals(Object var1);
 
    // 默认方法
    public default void defaultMethod(){
    
    }
 
    // 静态方法
    public static void staticMethod(){
 
    }
}

// 错误的函数式接口(有多个抽象方法)
@FunctionalInterface
public interface TestInterface2 {

    void add();
    
    void sub();
}

一个简单例子
定义一个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!

JDK中的函数式接口举例

java.lang.Runnable,

java.awt.event.ActionListener,

java.util.Comparator,

java.util.concurrent.Callable

java.util.function包下的接口,如Consumer、Function、Predicate、Supplier等
参考资料 Java 8之FunctionalInterface深度解析(一)

函数式接口@FunctionalInterface

发布了80 篇原创文章 · 获赞 140 · 访问量 64万+

猜你喜欢

转载自blog.csdn.net/linjpg/article/details/104096062