函数式接口核心是仅含一个抽象方法,用于支持lambda表达式;可含多个default、static方法及object类方法,推荐用@functionalinterface注解校验。

Java 中定义函数式接口,核心就一条:接口里只能有一个抽象方法。Lambda 表达式不是随便能用的,它必须绑定到这样一个“单抽象方法”的接口上,才能被编译器识别并实例化。
函数式接口的基本定义方式
用 @FunctionalInterface 注解标记接口,是明确表达设计意图的推荐做法。虽然不加这个注解、只要满足“仅一个抽象方法”条件,Java 也认它是函数式接口,但加上后编译器会主动检查——一旦你误加了第二个抽象方法,立刻报错,避免后期隐患。
- 接口中可以有多个 默认方法(default) 和 静态方法(static),它们不影响函数式接口判定
- 可以继承 Object 类的方法(比如 toString()、equals()),这些也不算抽象方法
- 抽象方法不能重载成多个签名相同但返回值不同的版本,否则会被视为多个抽象方法
一个标准的自定义函数式接口示例
下面这个接口只声明了一个抽象方法 getValue(),其他都是默认或静态方法,完全符合规范:
@FunctionalInterface<br>public interface Calculator {<br> // 唯一抽象方法 —— Lambda 就实现它<br> double calculate(double a, double b);<br><br> // 默认方法:不破坏函数式接口性质<br> default double square(double x) {<br> return x * x;<br> }<br><br> // 静态方法:同样允许<br> static boolean isPositive(double x) {<br> return x > 0;<br> }<br>}之后就可以用 Lambda 直接创建其实例:
Calculator add = (a, b) -> a + b;<br>Calculator multiply = (a, b) -> a * b;<br>System.out.println(add.calculate(3, 5)); // 输出 8
为什么必须配合 Lambda 使用?
Lambda 表达式本质是函数式接口的**匿名实例**。它不写类名、不写方法名,只提供那个唯一抽象方法的实现逻辑。编译器靠接口的抽象方法签名(参数类型、返回值)来推断 Lambda 的结构。
- 比如 Runnable 接口只有 run():void run() → 对应 () -> { ... }
- 比如 Comparator
只有 compare():int compare(String, String) → 对应 (s1, s2) -> s1.length() - s2.length() - 如果接口有两个抽象方法,编译器就无法确定 Lambda 到底在实现哪一个,直接拒绝编译
常用内置函数式接口可直接拿来用
JDK 已提供一批开箱即用的函数式接口,基本覆盖常见场景,一般无需自己重复造轮子:
-
Consumer
:接受一个参数,无返回值(如 list.forEach(item -> System.out.println(item))) -
Function
:接受一个参数,返回一个结果(如 strings.stream().map(String::toUpperCase)) -
Predicate
:接受一个参数,返回 boolean(如 list.stream().filter(s -> s.length() > 3)) -
Supplier
:无参,返回一个结果(如 Optional.ofNullable(x).orElseGet(() -> new DefaultObj()))
这些接口都标有 @FunctionalInterface,可放心配合 Lambda 使用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











