@FunctionalInterface 是编译期契约注解,强制接口有且仅有一个抽象方法,否则编译失败;它不改变运行时行为,但提升可读性、协作安全与IDE支持。

@FunctionalInterface 本身不运行时生效,也不改变接口行为,它的作用完全在编译阶段——用作一种契约式声明+编译器强制校验工具。
它怎么“强制约束”?
当你在接口上加上 @FunctionalInterface,编译器会立刻检查该接口是否满足函数式接口的唯一核心条件:有且仅有一个抽象方法。只要不满足,编译直接失败,不会生成 class 文件。
- 接口里写了两个未实现的抽象方法(比如同时有
validate()和canApply())→ 编译报错 - 继承了两个父接口,各自带一个抽象方法,子接口没用
default覆盖 → 编译报错 - 把
default方法误删了关键字,变成void log() {}(实际成了抽象方法)→ 编译报错 - 只声明了
String toString();(覆盖 Object 方法)→ 不计入,不报错 - 加了
static void helper(){}或多个default方法 → 允许,不干扰判定
不加 @FunctionalInterface 就不安全了吗?
不是。只要接口客观上只有一个抽象方法,它就是函数式接口,Lambda 和方法引用照样能用。但缺少注解意味着:
- 其他开发者无法一眼识别设计意图
- 后续有人无意中加了第二个抽象方法,编译器不会提醒,可能埋下隐患
- IDE 的自动提示、重构支持(如“提取为函数式接口”)可能降级
真正起约束作用的是编译器,不是注解本身
@FunctionalInterface 是一个“触发器”,不是“魔法”。它激活 javac 对接口结构的严格扫描。这种检查是静态的、即时的、零成本的——没有反射、不占运行时资源,却极大提升了接口定义的可靠性与协作效率。










