方法引用::是替代单行纯转发型lambda的手段,分为静态方法引用(如integer::parseint)、特定对象实例方法引用(如system.out::println)、任意对象实例方法引用(如string::touppercase)和构造器/数组引用(如arraylist::new),仅当lambda体严格转发参数时才适用。

在 Stream 流中,方法引用 :: 是替代单行、纯转发型 Lambda 表达式的直接手段——它不改变逻辑,只让代码更紧凑、语义更明确。关键不是“能不能写”,而是“是否符合转发本质”:Lambda 体必须只做一件事——把参数原样传给已有方法。
静态方法引用:工具类调用一目了然
当 Lambda 仅调用某个类的静态方法,且参数个数、类型、顺序完全匹配时,直接用 类名::静态方法名 替代。
-
s -> Integer.parseInt(s)→Integer::parseInt -
s -> String.valueOf(s)→String::valueOf -
x -> Math.abs(x)→Math::abs
注意:编译器会严格校验签名。比如 Long::parseLong 不能用于 Function<string integer></string>,因为返回类型不匹配。
特定对象的实例方法引用:固定接收者执行操作
当 Lambda 是对同一个对象反复调用其实例方法(如打印、格式化),用 对象::方法名。
-
s -> System.out.println(s)→System.out::println -
s -> formatter.format(s)→formatter::format
这里 System.out 是确定的对象,println 是它的实例方法,Stream 中每个元素自动作为参数传入。
任意对象的实例方法引用:方法属于参数本身
当 Lambda 实际是“对每个元素调用自己的某个方法”,用 类型::方法名。
-
s -> s.toUpperCase()→String::toUpperCase -
s -> s.length()→String::length -
p -> p.getName()→Person::getName
这种写法隐含“调用者就是流中当前元素”,常用于 map 或 sorted(Comparator.comparing(...)) 场景。
构造器与数组引用:创建动作干净利落
当 Lambda 作用是新建对象或数组,用 类名::new 或 类型[]::new。
-
() -> new ArrayList()→ArrayList::new -
(name, age) -> new Person(name, age)→Person::new(需存在对应构造器) -
len -> new int[len]→int[]::new
适用于 map 转换、collect 的 Collector.of,或 Stream.generate 后的 limit(n).toArray(int[]::new)。
不复杂但容易忽略:方法引用不是语法糖装饰,而是编译期绑定的语义精简。只要 Lambda 体里有变量计算、条件判断、多个语句或副作用,就不可替换——强行改会导致编译失败或行为错乱。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











