函数式接口是仅含一个抽象方法的接口,用于支持Lambda表达式;可含多个默认或静态方法,@FunctionalInterface注解非强制但推荐,编译器据此验证合法性。

函数式接口(FunctionalInterface)是只包含一个抽象方法的接口,Lambda表达式正是为它而生——用简洁语法实现该接口的唯一抽象方法,无需写冗长的匿名内部类。
什么是函数式接口
只要接口满足“仅有一个未被重写的抽象方法”,就可被 @FunctionalInterface 注解标记(非强制但推荐)。例如:
- Runnable:只有一个 run() 方法
- Comparator:只有一个 compare(T, T) 方法
- Predicate<T>、Function<T,R>、Consumer<T> 等 JDK 提供的函数式接口
如何定义并使用自定义函数式接口
先定义接口,再用 Lambda 实现它。比如校验字符串是否合法:
@FunctionalInterface
interface StringValidator {
boolean isValid(String s);
}
使用时直接传入 Lambda 表达式:
-
不带参数或单参数时可省略括号:如
s -> s != null && !s.trim().isEmpty() -
多参数必须加括号:如
(s1, s2) -> s1.length() == s2.length() -
方法体多行需加大括号和 return:如
s -> { System.out.println(s); return s.length() > 0; }
Lambda 如何匹配函数式接口的抽象方法
编译器根据目标类型(即变量声明类型或方法参数类型)自动推断 Lambda 的签名,要求:
- 参数数量、类型与抽象方法一致
- 返回值类型兼容(void 或可隐式转换)
- 抛出的异常不能超出抽象方法声明的范围
例如:Predicate<String> p = s -> s.startsWith("A"); 中,s 被推断为 String 类型,返回 boolean,完全匹配 Predicate 的 test 方法。
常见误用与注意事项
避免把 Lambda 乱塞给非函数式接口;也别在已有多个抽象方法的接口上硬加 @FunctionalInterface —— 编译会报错。
- 接口中 default 方法、static 方法不影响函数式接口性质
- Object 的 public 方法(如 toString、equals)也不算抽象方法
- Lambda 本质是函数式接口的实例,不是独立类型,不能直接赋值给 Object 或其他无关引用

















