📘 Java 方法引用(Method Reference)详细教程
Java 8 引入了方法引用(Method Reference)语法,它是 Lambda 表达式的一种简洁写法,可以更清晰地表达某些行为参数化场景。
✅ 方法引用的4种形式
| 类型 | 示例 | 等价 Lambda 表达式 |
|---|---|---|
| 引用静态方法 | ClassName::staticMethod |
(x) -> ClassName.staticMethod(x) |
| 引用特定对象的实例方法 | instance::instanceMethod |
(x) -> instance.instanceMethod(x) |
| 引用某个类的实例方法 | ClassName::instanceMethod |
(obj, arg) -> obj.instanceMethod(arg) |
| 引用构造器 | ClassName::new |
() -> new ClassName() |
📌 所用函数式接口参考(来自 java.util.function)
| 接口 | 方法签名 | 描述 |
|---|---|---|
Function<T, R> |
R apply(T t) |
接收 T 返回 R |
Consumer<T> |
void accept(T t) |
接收 T 无返回 |
Supplier<T> |
T get() |
无参返回 T |
Predicate<T> |
boolean test(T t) |
接收 T 返回 boolean |
BiFunction<T, U, R> |
R apply(T t, U u) |
接收 T、U 返回 R |
🔎 详细实例
1️⃣ 引用静态方法:ClassName::staticMethod
import java.util.function.Function;
public class StaticMethodRef {
public static int square(int x) {
return x * x;
}
public static void main(String[] args) {
// 使用方法引用调用静态方法 square
Function<Integer, Integer> func = StaticMethodRef::square;
System.out.println(func.apply(6)); // 输出:36
}
}
说明:StaticMethodRef::square 引用了静态方法 square,等价于 Lambda 表达式 (x) -> StaticMethodRef.square(x)。
2️⃣ 引用特定对象的实例方法:instance::instanceMethod
import java.util.function.Consumer;
public class InstanceMethodRef {
public void print(String msg) {
System.out.println("输出: " + msg);
}
public static void main(String[] args) {
InstanceMethodRef obj = new InstanceMethodRef();
// 使用方法引用调用 obj 的 print 方法
Consumer<String> consumer = obj::print;
consumer.accept("方法引用真香!"); // 输出:输出: 方法引用真香!
}
}
说明:obj::print 引用了 obj 对象的 print 方法,等价于 Lambda 表达式 (msg) -> obj.print(msg)。
3️⃣ 引用某个类的实例方法:ClassName::instanceMethod
import java.util.function.BiPredicate;
public class ClassInstanceMethodRef {
public static void main(String[] args) {
// 使用方法引用调用 String 的 equalsIgnoreCase 方法
BiPredicate<String, String> equalsIgnore = String::equalsIgnoreCase;
System.out.println(equalsIgnore.test("java", "JAVA")); // 输出:true
}
}
说明:String::equalsIgnoreCase 引用了 String 类的实例方法 equalsIgnoreCase,等价于 Lambda 表达式 (s1, s2) -> s1.equalsIgnoreCase(s2)。注意,第一个参数 s1 成为方法调用的对象。
4️⃣ 引用构造器:ClassName::new
import java.util.function.Supplier;
class Person {
String name = "默认名";
}
public class ConstructorRef {
public static void main(String[] args) {
// 使用方法引用调用 Person 的无参构造器
Supplier<Person> supplier = Person::new;
Person p = supplier.get();
System.out.println(p.name); // 输出:默认名
}
}
说明:Person::new 引用了 Person 类的无参构造器,等价于 Lambda 表达式 () -> new Person()。
🧩 方法引用结合 Stream 使用示例
import java.util.Arrays;
import java.util.List;
public class StreamMethodRef {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 使用 Lambda 表达式打印每个名字
names.forEach(name -> System.out.println(name));
// 使用方法引用,效果相同但更简洁
names.forEach(System.out::println);
}
}
说明:System.out::println 引用了 System.out 对象的 println 方法,等价于 Lambda 表达式 name -> System.out.println(name)。方法引用使代码更简洁,意图更清晰。
📚 小结
- 方法引用是 Lambda 表达式的简写形式;
- 可读性更强,代码更简洁;
- 常与函数式接口(如
Function、Consumer、Supplier等)结合使用; - 常见于 Stream、事件回调、异步处理等场景。