consumer接口专为无返回值的副作用操作设计,其核心方法void accept(t t)仅接收参数不返回结果,适用于日志记录、状态更新等场景,误用包括试图返回值或链式传递对象。

Consumer 接口专为“只消费、不返回”场景设计,适合执行日志记录、数据修改、状态更新等无返回值的副作用操作。
理解 Consumer 的核心契约
它只有一个抽象方法:void accept(T t),接收一个参数,不返回任何值(void)。这决定了它天然适合表达“对某个对象做点什么”,而非“算出什么结果”。
常见误用是试图在 lambda 里 return 一个值,或期望它链式返回处理后的对象——这是 Function 或 UnaryOperator 的职责,不是 Consumer 的定位。
典型副作用场景与写法
以下都是符合语义的正当用法:
- 更新对象内部状态:如设置字段、调用 setter、修改集合内容
- 触发外部行为:如打印日志、发通知、写缓存、调用 API(忽略响应)
- 资源清理辅助:如关闭流、释放锁(配合 try-with-resources 或手动管理时作为回调)
实用写法示例
✅ 正确(简洁、语义清晰):
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
Consumer<user> updateUserStatus = user -> {
user.setLastLoginTime(Instant.now());
user.setStatus("ACTIVE");
};</user>
✅ 带日志的副作用:
Consumer<order> logAndArchive = order -> {
System.out.println("Archiving order: " + order.getId());
order.markAsArchived();
};</order>
✅ 组合多个 Consumer(使用 andThen):
Consumer<payment> validate = p -> { /* 校验逻辑 */ };
Consumer<payment> persist = p -> { /* 存库 */ };
Consumer<payment> completeFlow = validate.andThen(persist);</payment></payment></payment>
注意边界与陷阱
Consumer 不承诺线程安全,若用于并发场景(如 Stream.parallelStream().forEach),需自行同步或确保操作本身是幂等/线程安全的。
避免在 accept 中抛出受检异常(如 IOException),否则需包装成 RuntimeException,或改用自定义函数式接口。
不要把它当“万能处理器”:如果业务逻辑需要返回新对象、转换类型、或可能失败并需处理异常,应选择 Function、Supplier、Runnable 或专门封装的接口。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










