java函数式接口是仅含一个抽象方法的接口,专为支持lambda表达式和方法引用而设计;允许default、static及object类方法,推荐用@functionalinterface注解触发编译检查。

Java 函数式接口的核心就一条:它是一个**只含一个抽象方法的接口**,专为配合 Lambda 表达式和方法引用而设计。定义不难,但关键在规则清晰、用得准确。
定义函数式接口的硬性要求
必须满足三个基本条件:
- 只能是 interface(不能是类或抽象类)
- 有且仅有一个抽象方法(即没有实现体、需被重写的方法)
- 允许存在任意数量的 default 方法、static 方法,以及重写 Object 类的 public 方法(如 toString、equals),这些都不算抽象方法
强烈建议加上 @FunctionalInterface 注解——它不是语法必需,但能触发编译器检查。一旦接口多了一个抽象方法,编译直接报错:Unexpected @FunctionalInterface annotation,帮你提前避坑。
怎么用内置函数式接口
JDK 提供了大量开箱即用的函数式接口,覆盖高频场景。常用四个核心接口及其典型用法:
-
Consumer
:接收一个参数,不返回值。适合“执行动作”,比如 list.forEach(System.out::println) -
Supplier
:无参,返回一个值。适合延迟创建,比如 Stream.generate(() -> new User()) -
Function
:接收 T,返回 R。支持链式处理,比如 s -> s.trim().toUpperCase(),还可组合andThen或compose -
Predicate
:接收 T,返回 boolean。用于条件筛选,比如 users.stream().filter(u -> u.getAge() > 18)
自定义函数式接口的实用技巧
当内置接口语义不够明确时,自定义更直观、更安全:
- 接口名要体现业务意图,比如
RetryPolicy、Validator<string></string>,而不是泛泛叫Operation - 避免过度泛型,优先用具体类型或有限泛型参数,例如
interface StringProcessor { String process(String s); } - 定义后可直接用 Lambda 实现:
StringProcessor upper = s -> s.toUpperCase();,也可作为方法参数传递,实现行为参数化
Lambda 和方法引用怎么对接口
函数式接口是 Lambda 的“容器”,两者必须类型匹配:
- Lambda 形参个数、类型、返回值,要和接口中那个唯一抽象方法完全一致
- 方法引用也一样:
String::trim可赋给Function<string string></string>,因为trim()无参、返回 String - 常见错误:把
Runnable(无参无返回)误当成Supplier(无参有返回)用,编译会拒绝
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











