方法引用(Method Reference)
一、方法引用概述
1. 引入目的
方法引用 是 Java 8 引入的一种语法特性,用于在特定条件下 进一步简化 Lambda 表达式的写法,使代码更加简洁、可读。
当 Lambda 表达式中的代码 只是调用一个已有方法,并且参数形式完全一致时,就可以使用方法引用。
2. 基本格式
类型或对象 :: 方法名
其中 :: 被称为 方法引用运算符。
二、方法引用的基本示例
import java.util.ArrayList;
import java.util.List;
public class MethodDemo {
public static void main(String[] args) {
List<String> lists = new ArrayList<>();
lists.add("first");
lists.add("second");
lists.add("third");
// Lambda 表达式写法
lists.forEach(s -> System.out.println(s));
// 方法引用写法
lists.forEach(System.out::println);
}
}
说明:
forEach需要一个Consumer<String>println(String s)的参数列表与accept(String s)完全一致- 因此可以使用方法引用进行简化
三、静态方法引用
1. 语法格式
类名 :: 静态方法
2. 使用前提(非常重要)
-
被引用方法的 参数列表 必须与函数式接口的抽象方法 完全一致
-
返回值规则:
- 若抽象方法有返回值 → 被引用方法必须有返回值,且类型兼容
- 若抽象方法无返回值 → 被引用方法可有也可无返回值
3. 使用步骤
- 定义一个静态方法
- 确保方法参数与函数式接口抽象方法一致
- 使用
类名::方法名引用
4. 示例
定义静态方法(Student 类)
public class Student {
private String name;
private int age;
private String sex;
public Student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public int getAge() {
return age;
}
public static int compareByAge(Student s1, Student s2) {
return s1.getAge() - s2.getAge();
}
// getter 省略
}
使用静态方法引用
import java.util.*;
public class ComparatorDemo {
public static void main(String[] args) {
List<Student> lists = new ArrayList<>();
Student s1 = new Student("Leslie", 18, "Man");
Student s2 = new Student("John", 14, "Man");
Student s3 = new Student("Gym", 20, "Woman");
Collections.addAll(lists, s1, s2, s3);
// Lambda 表达式
Collections.sort(lists, (t1, t2) -> Student.compareByAge(t1, t2));
// 静态方法引用
Collections.sort(lists, Student::compareByAge);
for (Student stu : lists) {
System.out.printf(
"name=%s age=%d sex=%s%n",
stu.getName(), stu.getAge(), stu.getSex()
);
}
}
}
四、实例方法引用
1. 语法格式
对象 :: 实例方法
2. 使用条件
- Lambda 表达式中 调用的是某个对象的实例方法
- 参数列表与函数式接口抽象方法完全一致
3. 示例说明
lists.forEach(System.out::println);
println是PrintStream的实例方法System.out是PrintStream对象- 参数完全一致,因此可以使用实例方法引用
五、构造器引用
1. 语法格式
类名 :: new
2. 使用条件
- Lambda 表达式中 唯一目的就是创建对象
- 构造器参数列表与函数式接口抽象方法参数列表一致
3. 示例
// Lambda 表达式
s -> new Student(s);
// 构造器引用
Student::new
常见使用场景:
mapcollect- 工厂方法
- 对象转换
六、方法引用的四种常见形式总结
| 类型 | 语法 | 示例 |
|---|---|---|
| 静态方法引用 | 类名::静态方法 | Student::compareByAge |
| 特定对象实例方法 | 对象::实例方法 | System.out::println |
| 任意对象实例方法 | 类名::实例方法 | String::length |
| 构造器引用 | 类名::new | Student::new |
七、小结
-
方法引用是 Lambda 表达式的语法糖
-
核心判断标准:能不能一一对应参数
-
使用方法引用可以:
- 提高代码可读性
- 减少冗余代码
- 更贴近函数式编程风格
-
当 Lambda 中包含复杂逻辑时,不应强行使用方法引用