函数接口

函数接口是指内部只有一个抽象方法的接口

Posted by 高明 on 2020-08-18

函数接口

函数接口

函数接口是指内部只有一个抽象方法的接口

通常函数接口出现的地方都可以使用Lambda表达式,所以不必记忆函数接口的名字

@FunctionalInterface说明

我们常用的一些接口CallableRunnableComparator等在JDK8中都添加了@FunctionalInterface注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
1
2
3
4
5
6
7
8
9
10
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}

FunctionalInterface接口

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

通过jdk8源码,可以知道这个注解有以下特性:

  1. 该注解只能标记在有且仅有一个抽象方法的接口上
  2. jdk8接口中的静态方法和默认方法,都不算抽象方法
  3. 接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中的方法,也不算抽象方法
  4. 该接口不是必须的,如果一个接口符合函数式接口定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionalInterface,那么编译器会报错

比如下面的接口就是一个正确的函数式接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@FunctionalInterface
public interface Comparator<T> {

// 抽象方法
int compare(T o1, T o2);

// java.lang.Object中的方法不是抽象方法
boolean equals(Object obj);

// default不是抽象方法
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}

// static不是抽象方法
public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
return Collections.reverseOrder();
}
}

参考文献

  1. JDK8新特性:函数式接口@FunctionalInterface的使用说明