System.out::println能直接用于forEach是因为它匹配Consumer接口。它是PrintStream的实例方法,签名void println(T)与Consumer.accept(T)一致,适用于forEach、peek等终端操作,但不可用于filter、map等中间操作。

在 Java 中,使用 System.out::println 作为方法引用配合 Stream 的 forEach,是最简洁直接的控制台输出方式。
为什么 System.out::println 能直接用?
因为 System.out 是 PrintStream 类型的对象,而 println 是它的一个实例方法,签名是 void println(T)(对任意类型 T 都有重载)。这恰好匹配 forEach 所需的 Consumer<t></t> 函数式接口——接受一个参数、无返回值。
常见写法示例
以下几种情况都能直接用 System.out::println:
- 打印字符串列表:
list.stream().forEach(System.out::println); - 打印数字流:
IntStream.range(1, 4).forEach(System.out::println); - 处理后输出:
list.stream().map(String::toUpperCase).forEach(System.out::println);
注意点:不能在中间操作中使用
方法引用只能用于终端操作(如 forEach、peek),不能放在中间操作(如 filter、map)里当参数。例如下面写法是错的:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
stream.filter(System.out::println) —— 编译不通过,因为 filter 需要 Predicate,不是 Consumer
替代写法与适用场景
如果需要额外逻辑(比如加前缀、格式化),就不能只靠方法引用,得用 lambda:
- 带格式输出:
stream.forEach(s -> System.out.println("[INFO] " + s)); - 避免空指针:
stream.filter(Objects::nonNull).forEach(System.out::println); - 调试时查看每一步:
stream.peek(System.out::println).map(...).forEach(...);


















