Java8 @FunctionalInterface
函数式接口的一大特性就是可以被lambda表达式和函数引用表达式代替。也就是说声明这样的接口,是可以灵活的以方法来传参。
《java8 的java.util.function包中函数式接口》
一、java8的函数式接口介绍
函数式接口其实就是一个抽象接口类,在Java 8之前已有的函数式接口有以下。
java.lang.Runnable
java.util.concurrent.Callable
java.util.Comparator
等等...
使用方法
其实上述所说的接口类只需要使用@FunctionalInterface注解修饰,就成为了Java中的函数式接口。比如JDK中Callable接口定义
@FunctionalInterface public interface Callable<V> { V call() throws Exception; }
函数式接口都将能用在lambda表达式上。
二、@FunctionalInterface注解源码
看看@FunctionalInterface的源码:
通过JDK8源码javadoc,可以知道这个注解有以下特点:
1、该注解只能标记在"有且仅有一个抽象方法"的接口上。
2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。
3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
4、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
三、@FunctionalInterface用法介绍
如果你确实需要创建自己的函数式接口,那么就这样用此注释标记。当你编写的代码里没有抽象方法或多于1个抽象方法时,IDE会报错:
并且如果你应用它到一个类而不是接口时,它会警告你:
正确的示例如下:
package com.dxz.jdk8; // 正确的函数式接口 @FunctionalInterface public interface TestInterface { // 抽象方法 public void sub(); // java.lang.Object中的方法不是抽象方法 public boolean equals(Object var1); // default不是抽象方法 public default void defaultMethod() { } // static不是抽象方法 public static void staticMethod() { } }
lambda表达式可用于带有一个单一抽象方法的任何接口,但它们不能用于符合相同标准的抽象类。似乎不合逻辑,但就是这样。