使用@FunctionalInterface注解声明函数式接口时,接口必须有且仅有一个抽象方法;可含任意default、static方法及Object类的public方法,否则编译失败。

直接在接口定义前加上 @FunctionalInterface 注解即可,前提是该接口**有且仅有一个抽象方法**。这不是可选项,而是明确表达设计意图并启用编译器保护的关键一步。
声明函数式接口的硬性条件
加了注解不等于就合法,必须满足以下规则,否则编译失败:
- 接口中只能存在一个抽象方法(即没有 default、static、private 修饰,且不是 Object 类继承来的方法)
- 可以有任意多个 default 方法(提供默认实现)
- 可以有任意多个 static 方法(通常作工具方法或工厂方法)
- 可以包含 equals、hashCode、toString 等来自 Object 的 public 方法,它们不计入抽象方法数量
正确写法示例
下面是一个标准、可直接用于 Lambda 的函数式接口:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
public interface Calculator {
int compute(int a, int b); // 唯一抽象方法
default void log(String op) {
System.out.println("Performed: " + op);
}
static int abs(int x) {
return x }
}
为什么必须加这个注解
不加也能被当作函数式接口用(只要结构符合),但加了才有实际价值:
立即学习“Java免费学习笔记(深入)”;
- 防止误改:后续有人往接口里加第二个抽象方法时,编译器立刻报错,而不是等所有 Lambda 调用处崩溃
- 意图清晰:一眼看出这是为函数式编程服务的接口,不是普通业务契约接口
- 团队协作友好:相当于在代码里写文档——“别在这加抽象方法,它专供 Lambda 或方法引用”
常见错误写法
这些写法即使加了注解也会编译失败:
- 接口里定义了两个抽象方法(如同时有
void run()和void stop()) - 抽象方法被 private 或 protected 修饰(Java 接口方法默认 public abstract,不能降级)
- 把
@FunctionalInterface错误地加在类、方法或抽象类上(它只作用于 interface)

















