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深度解析(一)