@FunctionalInterface注解在编译期由javac校验接口是否满足函数式接口条件:有且仅有一个抽象方法,default、static及重写Object的方法不计入;不满足则编译失败,加注解可明确意图并防止误改。

@FunctionalInterface 注解本身不执行运行时校验,它只是告诉编译器:“请严格检查这个接口是否满足函数式接口的核心条件”——即有且仅有一个抽象方法。校验动作由 javac 在编译期自动触发,一旦不满足就报错,不生成 class 文件。
校验的三项硬性规则
加了注解后,编译器会逐条检查以下内容,任一不满足即中断编译:
- 接口中声明的抽象方法数量必须恰好为 1(不能是 0,也不能 ≥2)
- 不能出现 private 抽象方法、构造器、实例字段等违反接口语义的成员
- 所有方法定义必须符合 Java 接口语法规范(比如 abstract 关键字不能缺失,除非是 default 或 static)
哪些方法不参与抽象方法计数
以下三类方法存在,不影响“单抽象方法”的判定,也不会引发编译错误:
- default 方法:带方法体,可任意多个
- static 方法:带方法体,可任意多个
- 重写 Object 的 public 方法:如 toString()、equals(Object)、hashCode(),即使没显式写出,也默认视为已存在且不计数
常见编译失败场景
这些错误在保存或构建时立刻暴露,不是运行时异常:
立即学习“Java免费学习笔记(深入)”;
- 接口里写了两个抽象方法(例如 void start(); void stop();)→ 报错:Multiple non-overriding abstract methods
- 继承了两个父接口,各自含一个未被覆盖的抽象方法 → 总数超 1,编译失败
- 只写了 default 方法,没写任何抽象方法 → 报错:No abstract method found
- 把 default void log() {} 误删成 void log() {}(少了 default)→ 变成抽象方法,若此时已有另一个抽象方法,就触发多方法报错
不加注解也能用 Lambda,为什么还要加?
不加 @FunctionalInterface,只要接口客观上只有一个抽象方法,Lambda 依然可用。但加上注解才有实际价值:
- 明确设计意图,让其他开发者一眼看懂这是为函数式编程准备的接口
- 防止后续误改:别人不小心加第二个抽象方法时,编译器马上拦截
- 增强 IDE 支持,比如自动补全 Lambda、重构提示、跳转查看更清晰


















