函数式接口必须有且仅有一个抽象方法,需用interface声明,可含任意default、static及object重写方法;@functionalinterface注解非必需但强烈推荐,用于明确意图并触发编译校验。

函数式接口的核心是“有且仅有一个抽象方法”,定义时要确保这个约束成立,再用 @FunctionalInterface 注解显式标记,让编译器帮你把关。
必须满足的三个硬性条件
一个接口要合法成为函数式接口,得同时满足:
- 必须用
interface声明,不能是类或抽象类 - 抽象方法只能有 1 个(即没方法体、必须被实现的方法)
- 可以自由添加任意数量的
default方法、static方法,以及重写Object类的toString()、equals()、hashCode()——这些都不算抽象方法
@FunctionalInterface 注解的作用
这个注解不是语法必需,但强烈推荐加上。它有两个实际价值:
- 明确表达设计意图:告诉其他开发者“这个接口就是用来配合 Lambda 的”
- 触发编译器校验:如果接口里不小心加了第二个抽象方法,编译直接报错
Unexpected @FunctionalInterface annotation,避免后期出问题
合法定义示例与常见误区
下面写法是合规的:
@FunctionalInterface
public interface Calculator {
int calculate(int a, int b); // ✅ 唯一抽象方法
default void printResult(int result) {
System.out.println("Result: " + result);
} // ✅ 默认方法,不破坏函数式接口性质
static void logStart() {
System.out.println("Calculation started");
} // ✅ 静态方法,允许存在
// ✅ 重写 Object 方法,也不计入抽象方法数量
@Override
boolean equals(Object obj);
}
而下面这种会编译失败:
@FunctionalInterface
public interface BadExample {
void doFirst();
void doSecond(); // ❌ 两个抽象方法 → 编译报错
}
什么时候可以省略 @FunctionalInterface?
技术上可以省略,只要接口确实只有一个抽象方法,Lambda 就能用。但不建议:
- 失去编译期防护,后续维护中容易误加抽象方法而不自知
- 语义不清晰,别人读代码时无法一眼判断设计用途
- IDE 和静态检查工具可能无法提供对应提示或补全支持










