@FunctionalInterface注解
@FunctionalInterface 是 Java 8 引入的一个注解,用于标识一个函数式接口(Functional Interface)。它的核心作用是明确接口的设计意图,并让编译器帮助检查接口是否符合函数式接口的规范。
1. 什么是函数式接口?
函数式接口是指只包含一个抽象方法(但可以包含多个默认方法或静态方法)的接口。它可以用作 Lambda 表达式 或 方法引用 的目标类型。
常见的函数式接口:
Runnable(void run())Callable(V call())Comparator(int compare(T a, T b))- Java 8 新增的
java.util.function包中的接口(如Predicate、Function、Consumer等)
2. @FunctionalInterface 的作用
(1) 明确设计意图
- 告诉其他开发者,这个接口是专门为 Lambda 表达式设计的。
- 避免后续误添加新的抽象方法导致接口不再是函数式接口。
(2) 编译器检查
- 如果接口被
@FunctionalInterface标注,但不符合函数式接口的定义(如包含多个抽象方法),编译器会报错。
示例:
@FunctionalInterface
interface MyFunctionalInterface {
void doSomething(); // 只有一个抽象方法,合法
// void doAnother(); // 如果取消注释,编译器会报错
}
3. 函数式接口的特点
- 只能有一个抽象方法(但可以有
default或static方法)。 - 可以包含
Object类中的方法(如toString()、equals()),这些不算抽象方法。 - 可以用 Lambda 表达式或方法引用实现。
示例:
@FunctionalInterface
interface Calculator {
int calculate(int a, int b); // 唯一抽象方法
default void print() {
System.out.println("This is a default method.");
}
static void info() {
System.out.println("This is a static method.");
}
}
public class Main {
public static void main(String[] args) {
// Lambda 表达式实现
Calculator add = (a, b) -> a + b;
Calculator subtract = (a, b) -> a - b;
System.out.println(add.calculate(5, 3)); // 输出 8
System.out.println(subtract.calculate(5, 3)); // 输出 2
add.print(); // 调用 default 方法
Calculator.info(); // 调用 static 方法
}
}
4. 为什么需要 @FunctionalInterface?
- 代码可读性:明确表示该接口用于 Lambda 表达式。
- 防止错误:避免因误添加抽象方法导致接口无法用于 Lambda 表达式。
- 兼容性:即使没有
@FunctionalInterface注解,只要接口符合函数式接口的定义,仍然可以作为 Lambda 的目标类型。但加上注解更安全。
5. 自定义函数式接口
你可以自己定义函数式接口,例如:
@FunctionalInterface
interface StringFormatter {
String format(String input);
}
public class Main {
public static void main(String[] args) {
StringFormatter toUpper = str -> str.toUpperCase();
StringFormatter addExclamation = str -> str + "!";
System.out.println(toUpper.format("hello")); // 输出 "HELLO"
System.out.println(addExclamation.format("Hi")); // 输出 "Hi!"
}
}
6. 常见内置函数式接口
Java 8 在 java.util.function 包中提供了许多内置函数式接口,例如:
Predicate<T>:接收参数,返回boolean(test(T t))。Function<T, R>:接收参数,返回结果(apply(T t))。Consumer<T>:接收参数,无返回值(accept(T t))。Supplier<T>:无参数,返回结果(get())。UnaryOperator<T>:接收并返回同类型参数(apply(T t))。
示例:
import java.util.function.*;
public class Main {
public static void main(String[] args) {
Predicate<String> isEmpty = s -> s.isEmpty();
System.out.println(isEmpty.test("")); // true
Function<Integer, String> intToString = i -> "Number: " + i;
System.out.println(intToString.apply(5)); // "Number: 5"
Consumer<String> print = System.out::println;
print.accept("Hello, Functional Interface!");
}
}
总结
| 特性 | 说明 |
|---|---|
@FunctionalInterface |
标识接口为函数式接口,编译器会检查是否符合规范 |
| 抽象方法限制 | 只能有一个抽象方法(可包含 default 或 static 方法) |
| Lambda 适用 | 可用于 Lambda 表达式或方法引用 |
| 内置接口 | Java 8 提供 Predicate、Function、Consumer 等常用接口 |
| 自定义 | 可以自己定义函数式接口 |
关键点:
- 函数式接口的核心是只有一个抽象方法。
@FunctionalInterface是可选的,但推荐使用以提高代码可读性和安全性。- Lambda 表达式让函数式接口的使用更加简洁。

浙公网安备 33010602011771号