函数式接口必须有且仅有一个抽象方法,需标注@functionalinterface注解以启用编译期校验;允许默认方法、静态方法及重写object方法,但禁止第二个抽象方法,其设计核心是明确行为契约、语义清晰、复用性强。

函数式接口的设计不是随意命名加一个抽象方法就行,关键在于明确意图、控制粒度、兼顾复用与语义清晰。它本质上是为行为建模,而不是为类建模。
聚焦单一行为契约
接口只暴露一个抽象方法,且该方法名要准确反映其职责。比如想封装“校验逻辑”,就用 PredicateOperation 的接口再塞进多个方法。方法签名(参数类型、返回类型、是否抛异常)必须稳定,一旦发布就尽量避免变更。
- 避免把多个语义不同的操作合并到一个接口里(如同时含
process()和validate()) - 抽象方法不要重载——重载会破坏 Lambda 的类型推断
- 若需扩展能力(如组合、默认行为),用默认方法,而非新增抽象方法
善用泛型与类型约束
泛型参数不是装饰,而是契约的一部分。设计时要考虑实际使用场景中的类型边界和可读性:
- 输入/输出类型尽量具体,避免过度泛化(如不用
Object,而用String或业务实体) - 必要时用泛型限定(
<t extends comparable>></t>)提前暴露约束,让错误发生在编译期 - 避免在接口中引入多个无关泛型参数(如
MyFunc<a b c d></a>),超过 2 个通常说明职责过重
默认方法用于增强,而非替代抽象方法
默认方法适合提供通用辅助逻辑,比如组合、包装、空安全处理,但不能改变接口的核心契约:
- 例如 Predicate 提供
and()、or()、negate(),都是基于已有test()的组合,不新增行为维度 - 不要在默认方法里强制要求子类实现某个新能力(那应该抽成新接口)
- 避免默认方法之间相互调用形成隐式依赖链,增加理解成本
注解与文档同步表达设计意图
@FunctionalInterface 是必需的,不是可选项。它不只是编译检查,更是对维护者和调用者的显式提醒:
- 加上注解后,IDE 和编译器会立刻报错:新增抽象方法、继承了另一个函数式接口、误写了未实现的 Object 方法等
- Javadoc 要写清楚这个接口代表什么行为、典型使用场景、线程安全性(如有)、是否允许 null 输入等
- 接口名应直白,优先复用 JDK 已有命名习惯(如
Converter、Checker、Mapper),避免造词如Doer、Handler
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











