方法引用
字数: 0 字 时长: 0 分钟
1. 概述
在使用 Lambda 表达式时,如果方法体中只有一个方法调用,包括构造方法,可以使用方法引用进一步简化代码。
例如:
java
authors.stream()
.map(age -> String.valueOf(age));可以简化为:
java
authors.stream()
.map(String::valueOf);方法引用本质上是 Lambda 表达式的一种简化写法。
2. 推荐用法
实际开发中不需要刻意记住什么时候一定要使用哪一种方法引用。
一般写完 Lambda 后,如果发现:
- 方法体只有一条语句
- 这条语句只是调用另一个方法
- 参数和返回值能够对应
就可以尝试让 IDEA 自动转换成方法引用。

3. 基本格式
方法引用的基本格式:
java
类名::方法名或者:
java
对象名::方法名构造器引用:
java
类名::new常见类型:
text
类的静态方法引用
对象的实例方法引用
类的实例方法引用
构造器引用4. 引用类的静态方法
4.1 格式
java
类名::静态方法名例如:
java
String::valueOf4.2 使用前提
当 Lambda 方法体中:
- 只有一行代码
- 调用了某个类的静态方法
- Lambda 的参数按照顺序传递给该静态方法
就可以尝试使用静态方法引用。

原始写法:
java
authors.stream()
.map(new Function<Author, Integer>() {
@Override
public Integer apply(Author author) {
return author.getAge();
}
})
.map(new Function<Integer, String>() {
@Override
public String apply(Integer age) {
return String.valueOf(age);
}
});Lambda 简化:
java
authors.stream()
.map(author -> author.getAge())
.map(age -> String.valueOf(age));使用方法引用:
java
authors.stream()
.map(author -> author.getAge())
.map(String::valueOf);这里:
java
age -> String.valueOf(age)可以直接转换为:
java
String::valueOf如果 Lambda 没有参数,而调用的方法同样没有参数,也可能满足方法引用的条件。
5. 引用对象的实例方法
5.1 格式
java
对象名::方法名例如:
java
sb::append5.2 使用前提
当 Lambda 方法体中:
- 只有一行代码
- 调用了某个已经存在对象的实例方法
- Lambda 的参数按照顺序传递给该实例方法
就可以使用对象的实例方法引用。

原始写法:
java
List<Author> authors = getAuthors();
StringBuilder sb = new StringBuilder();
authors.stream()
.map(new Function<Author, String>() {
@Override
public String apply(Author author) {
return author.getName();
}
})
.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
sb.append(s);
}
});Lambda 简化:
java
authors.stream()
.map(author -> author.getName())
.forEach(s -> sb.append(s));使用方法引用:
java
authors.stream()
.map(author -> author.getName())
.forEach(sb::append);这里:
java
s -> sb.append(s)可以直接转换为:
java
sb::append6. 引用类的实例方法
6.1 格式
java
类名::方法名例如:
java
String::substring这种写法和静态方法引用格式相同,但含义不同。
6.2 使用前提
当 Lambda 方法体中:
- 只有一行代码
- 调用的是第一个参数的实例方法
- Lambda 剩余的参数按照顺序传递给该实例方法
就可以使用类的实例方法引用。
可以理解为:
text
(str, start, end)
↓
str.substring(start, end)
↓
String::substring
定义函数式接口:
java
interface UseString {
String use(String str, int start, int end);
}定义方法:
java
public static String subAuthorName(String str, UseString useString) {
int start = 0;
int end = 1;
return useString.use(str, start, end);
}匿名内部类写法:
java
public static void main(String[] args) {
subAuthorName("kerwim", new UseString() {
@Override
public String use(String str, int start, int end) {
return str.substring(start, end);
}
});
}Lambda 写法:
java
subAuthorName(
"kerwim",
(str, start, end) -> str.substring(start, end)
);方法引用:
java
subAuthorName("kerwim", String::substring);这里:
java
(str, start, end) -> str.substring(start, end)可以直接转换为:
java
String::substring7. 构造器引用
如果 Lambda 方法体中只有一个构造方法调用,可以使用构造器引用。
7.1 格式
java
类名::new例如:
java
StringBuilder::new7.2 使用前提
当 Lambda 方法体中:
- 只有一行代码
- 调用了某个类的构造方法
- Lambda 的参数按照顺序传递给构造方法
就可以使用构造器引用。

Lambda 写法:
java
List<Author> authors = getAuthors();
authors.stream()
.map(author -> author.getName())
.map(name -> new StringBuilder(name))
.map(sb -> sb.append("-kerwim").toString())
.forEach(str -> System.out.println(str));使用构造器引用:
java
authors.stream()
.map(author -> author.getName())
.map(StringBuilder::new)
.map(sb -> sb.append("-kerwim").toString())
.forEach(str -> System.out.println(str));这里:
java
name -> new StringBuilder(name)可以直接转换为:
java
StringBuilder::new8. 小结
方法引用主要有四种形式:
| 类型 | 格式 | 示例 |
|---|---|---|
| 类的静态方法 | 类名::方法名 | String::valueOf |
| 对象的实例方法 | 对象名::方法名 | sb::append |
| 类的实例方法 | 类名::方法名 | String::substring |
| 构造器引用 | 类名::new | StringBuilder::new |
简单理解:
text
age -> String.valueOf(age)
↓
String::valueOf
s -> sb.append(s)
↓
sb::append
(str, start, end) -> str.substring(start, end)
↓
String::substring
name -> new StringBuilder(name)
↓
StringBuilder::new实际开发中先正常写 Lambda,如果 IDEA 提示可以转换成方法引用,再进行简化即可。