函数式接口是仅含一个抽象方法的接口,用于支持Lambda表达式和方法引用;必须满足单一抽象方法规则,可含默认方法、静态方法及Object类方法,推荐用@FunctionalInterface注解显式标记并由编译器校验。

Java 中的函数式接口是只声明一个抽象方法的接口,用于支持 Lambda 表达式和方法引用。它不是语法糖,而是编译器层面的契约约束。
定义函数式接口的关键规则
必须用 @FunctionalInterface 注解显式标记(虽非强制,但强烈建议),且接口中只能有一个抽象方法(默认方法、静态方法、Object 类继承的方法不计入)。
- 允许有多个 default 方法(如
Comparator中的reversed()、thenComparing()) - 允许有任意数量的 static 方法(如
Function.identity()) - 可以重写 Object 的 public 方法(如
toString()、equals()、hashCode()),这些不被视为抽象方法 - 若接口中意外出现两个抽象方法,编译器会报错:
Unexpected @FunctionalInterface annotation
常见内置函数式接口及典型用法
JDK 提供了大量预定义函数式接口,覆盖常见场景:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
Supplier<T>:无参、返回值,适合延迟创建对象,例如
Stream.generate(() -> new Date()) -
Consumer<T>:接受一个参数、无返回值,常用于遍历处理,例如
list.forEach(System.out::println) -
Function<T, R>:接受一个参数、返回结果,支持链式调用(
andThen/compose),例如s -> s.trim().toUpperCase() -
Predicate<T>:接收参数、返回 boolean,用于条件判断,例如
users.stream().filter(u -> u.getAge() > 18) - UnaryOperator<T> 和 BinaryOperator<T>:分别是 Function 和 BiFunction 的特化版本,入参与返回类型相同
自定义函数式接口的实用写法
当内置接口无法满足语义需求时,可定义语义清晰的接口,提升可读性与类型安全:
立即学习“Java免费学习笔记(深入)”;
- 接口名应体现用途,如
Validator<String>、RetryPolicy<Exception> - 避免泛型过度抽象,优先使用具体类型或有限泛型参数
- 示例:
@FunctionalInterface<br>public interface RetryPredicate<T> {<br> boolean shouldRetry(int attempt, T result, Throwable error);<br>} - Lambda 使用:
RetryPredicate<String> p = (a, r, e) -> e instanceof IOException;
与 Lambda 和方法引用的配合要点
Lambda 表达式本质是函数式接口的实例,其形参个数、类型、返回值必须严格匹配抽象方法签名:
- 单参数且无类型推断歧义时可省略括号:
str -> str.length() > 0 - 方法引用需保证签名一致,如
String::isEmpty可赋给Predicate<String> - 构造器引用(
ArrayList::new)对应 Supplier 或 Function 等含构造逻辑的接口 - 注意:Lambda 不能单独存在,必须上下文明确目标类型(如赋值、传参、返回)

















