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

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











