什么是函数式接口
函数式接口简单来说就是上面有@FunctionalInterface注解的接口
函数式接口的特点
总结了下它的三个特点:
- 首先它是一个接口,有接口的所有特点。
- 其次它只能有一个抽象方法。
- 我认为最重要的一点是它服务于Lambda表达式,它的很多设计都是源于这一点。
一个函数式接口的简单应用
代码:
@FunctionalInterface
public interface Say {
void fun(String name);
}
public class Test {
public static void sayHi(String name, Say say) {
say.fun(name);
};
public static void main(String[] args) {
sayHi("张三", (x) -> System.out.print("Hello " + x));
}
}
运行结果:
Hello 张三
函数式接口中允许定义的方法类型:
函数式接口中允许定义的方法类型有以下几种:
- 默认方法
- 静态方法
- Obeject类的public方法(虽然是抽象方法,但是不计入函数式接口的抽象方法个数,原因见下)
示例代码:
@FunctionalInterface
public interface Say {
void fun(String name); //抽象方法
static void talk(String name) { // 静态方法
System.out.println("Hi " + name);
}
default void play() { // 默认方法
};
@Override
int hashCode(); // Object类里的抽象方法
@Override
String toString();// Object类里的抽象方法
}
-
函数式接口只可以定义这几种方法的原因:
默认方法:默认方法有个默认实现。
静态方法:静态方法不能是抽象方法,已经被实现。
Object中的抽象方法:任何一个函数式接口的实现,默认都继承了Object类,包含了来自java.lang.Object里对这些抽象方法的实现。
总结起来就是这几种方法都已经有了实现,以保证Lambda表达式中的()调用的为实现的方法就是函数式接口中定义的抽象方法,而非别的方法,都是为了Lambda实现行为参数化考虑,如果有多个未实现的抽象方法就会出现多个指向,从而出现错误,如下图:
-------------------------------------------华丽的分割线------------------------------------------------
JDK中的函数式接口举例
- JDK 1.8 之前已有的函数式接口:
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener - JDK 1.8 新增加的函数接口:
java.util.function
以上内容参考: