方法引用是Java中用ClassName::method等简洁语法替代Lambda表达式的机制,前提是已有方法签名与函数式接口完全匹配,分为静态、特定实例和泛化实例三类,用于提升代码可读性与紧凑性。

方法引用在 Java 流(Stream)操作中,本质是用更简洁的写法代替 Lambda 表达式,前提是已有现成的方法满足函数式接口的签名。它不改变逻辑,只让代码更紧凑、可读性更高。
什么时候能用方法引用?
核心条件:你写的 Lambda 表达式,只是单纯调用一个已有方法,且参数数量、类型和返回值完全匹配函数式接口的抽象方法。
-
例如:
str -> str.toUpperCase()可简化为String::toUpperCase -
不能用的情况:
s -> s.length() > 5含逻辑判断,没有现成方法直接对应,就不能用方法引用 -
注意 this 和类名: 实例方法引用要用
对象引用::方法名或类名::实例方法名(此时第一个参数自动作为调用对象)
三类常见写法及对应场景
方法引用分三种形式,对应不同调用上下文:
-
静态方法引用:
ClassName::staticMethod比如Integer::parseInt替代s -> Integer.parseInt(s),常用于map或filter的转换 -
实例方法引用(特定对象):
object::instanceMethod比如list::contains替代x -> list.contains(x),适合filter中复用某个集合的判断逻辑 -
实例方法引用(泛化调用):
ClassName::instanceMethod比如String::startsWith替代(s, prefix) -> s.startsWith(prefix),适用于接收两个参数、第一个是调用方的函数式接口(如BiPredicate<string string></string>)
流操作中典型简化示例
对比写法一目了然:
立即学习“Java免费学习笔记(深入)”;
-
stream.map(x -> x.trim())→stream.map(String::trim) -
stream.filter(x -> x != null)→stream.filter(Objects::nonNull) -
stream.sorted((a, b) -> a.compareTo(b))→stream.sorted(String::compareTo) -
list.forEach(x -> System.out.println(x))→list.forEach(System.out::println)
注意事项和易错点
方法引用看着简单,但容易因签名不匹配报错:
-
参数顺序要对齐:
String::compareTo是(String) -> int形式,只能用于接受单个参数并返回 int 的函数式接口(如Comparator),不能直接用于Function<String, Integer> -
构造方法引用写法特殊:
ArrayList::new对应Supplier<List>或Function<Integer, List>等,取决于构造器参数个数 -
避免空指针:
obj::method中 obj 为空会立刻抛 NPE;而ClassName::method是延迟绑定,相对安全
不复杂但容易忽略细节,关键还是看函数式接口要什么,再找有没有方法刚好“长那样”。多写几次,自然就顺手了。


















