@functionalinterface 注解用于显式标记并强制校验接口有且仅有一个抽象方法,支持任意数量的 default 和 static 方法及 object 继承方法;加注解可防误改、提升可读性与编译期安全。

必须满足的核心条件
加了 @FunctionalInterface 的接口,编译器会严格检查以下三点:
- 接口中只能定义一个抽象方法(非 default、非 static、非 Object 继承的方法)
- 可以任意数量的 default 方法 和 static 方法
-
Object 类声明的方法(如
toString()、equals()、hashCode())不计入抽象方法数,不影响函数式接口判定
常见误用与避坑点
很多开发者以为加了注解就“自动变成函数式接口”,其实不然。以下是典型错误场景:
- 接口里写了两个抽象方法,哪怕都带参数类型差异,也会编译失败
- 继承了另一个接口,而父接口已有抽象方法,子接口又新增一个——总数超 1,加注解就报错
- 把
default方法误当成抽象方法删掉,结果只剩 0 个抽象方法,同样不通过校验
标准写法示例(含可复用结构)
一个干净、可直接用于 Lambda 的自定义函数式接口:
@FunctionalInterface
public interface StringProcessor {
// 唯一抽象方法(必须)
String transform(String input);
// default 方法:可选,不破坏函数式特性
default boolean isEmpty(String s) {
return s == null || s.trim().isEmpty();
}
// static 方法:也可存在,常用于工厂或工具逻辑
static String blankIfNull(String s) {
return s == null ? "" : s;
}
}
使用时直接赋值 Lambda:
StringProcessor upper = s -> s.toUpperCase(); StringProcessor trim = String::trim;
为什么推荐始终加上这个注解
不加也能用(只要事实满足单抽象方法),但加了才有真正价值:
- 防止后续维护者无意中添加第二个抽象方法,导致所有 Lambda 调用失效
- IDE 和编译器立刻反馈问题,而不是等到运行时报
BadFunctionalInterfaceException或编译不通过 - 代码意图一目了然:这个接口就是为函数式编程服务的,不是普通契约接口











