Lambda表达式仅调用已有方法且签名完全匹配时可用::简化;静态方法引用如Integer::parseInt,实例方法引用分固定对象(System.out::println)和任意对象(String::toUpperCase),构造器引用如ArrayList::new;须严格匹配函数式接口签名。

当 Lambda 表达式只做一件事:调用一个已存在的方法,且参数和返回值完全匹配时,就能用 :: 替代,代码立刻变短、意图更清楚。
静态方法引用:类名::静态方法名
适用于 Lambda 体就是“直接转发参数给某个静态工具方法”的场景。编译器会把 Lambda 的参数按顺序传给该静态方法。
-
Integer::parseInt 替代
s -> Integer.parseInt(s)(Function<String, Integer>) -
String::valueOf 替代
i -> String.valueOf(i)(Function<Integer, String>) -
Math::abs 替代
x -> Math.abs(x)(UnaryOperator<Integer>)
注意:形参个数、类型、顺序必须和静态方法声明严格一致。比如 Math.max(int, int) 有两个参数,就不能用于只接收一个参数的接口(如 Function)。
实例方法引用:分两种写法
一种是固定对象调用,一种是任意对象调用,语义不同,不能混用。
立即学习“Java免费学习笔记(深入)”;
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
-
System.out::println → 等价于
x -> System.out.println(x),x 是唯一入参,System.out 是固定调用者 -
String::toUpperCase → 等价于
s -> s.toUpperCase(),s 本身是调用对象,方法无额外参数 -
String::compareTo → 在 Comparator<String> 中可用,等价于
(a, b) -> a.compareTo(b),第一个参数隐式为调用者
别写错:若想用 String::compareToIgnoreCase 做排序,要小心——它不满足 Comparator 要求的严格偏序,可能引发运行时异常或不可靠结果。
构造方法与数组引用:消除 new 冗余
当 Lambda 只是创建对象,就用 ::new 替代。
-
ArrayList::new 替代
() -> new ArrayList<>()(Supplier) -
Person::new 替代
(n, a) -> new Person(n, a)(BiFunction),前提是存在对应构造器 -
int[]::new 替代
len -> new int[len](IntFunction)
构造器引用也要求参数数量和类型完全匹配,否则编译失败。
避坑提醒:不是所有 Lambda 都能换
强行套用 :: 会报错或语义出错,关键看三点:
- 目标类型必须是函数式接口(只有一个抽象方法)
- Lambda 方法体必须只有一行纯方法调用,不能有 if、+、!、null 判断等额外逻辑
- 被引用方法的签名(参数类型/个数/顺序 + 返回值)必须和函数式接口抽象方法一模一样
例如 (a, b) -> b.compareTo(a) 无法用 String::compareTo 替代,因为参数顺序反了;Objects.equals 有重载,直接写 Objects::equals 会编译失败,得加显式类型转换。

















