?? Java 方法引用(Method Reference)詳細(xì)教程
Java 8 引入了方法引用(Method Reference)語法,它是 Lambda 表達(dá)式的一種簡潔寫法,可以更清晰地表達(dá)某些行為參數(shù)化場景。
? 方法引用的4種形式
| 類型 | 示例 | 等價 Lambda 表達(dá)式 |
|---|---|---|
| 引用靜態(tài)方法 | ClassName::staticMethod |
(x) -> ClassName.staticMethod(x) |
| 引用特定對象的實(shí)例方法 | instance::instanceMethod |
(x) -> instance.instanceMethod(x) |
| 引用某個類的實(shí)例方法 | ClassName::instanceMethod |
(obj, arg) -> obj.instanceMethod(arg) |
| 引用構(gòu)造器 | ClassName::new |
() -> new ClassName() |
?? 所用函數(shù)式接口參考(來自 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 |
?? 詳細(xì)實(shí)例
1?? 引用靜態(tài)方法: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) {
// 使用方法引用調(diào)用靜態(tài)方法 square
Function<Integer, Integer> func = StaticMethodRef::square;
System.out.println(func.apply(6)); // 輸出:36
}
}
說明:StaticMethodRef::square 引用了靜態(tài)方法 square,等價于 Lambda 表達(dá)式 (x) -> StaticMethodRef.square(x)。
2?? 引用特定對象的實(shí)例方法: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();
// 使用方法引用調(diào)用 obj 的 print 方法
Consumer<String> consumer = obj::print;
consumer.accept("方法引用真香!"); // 輸出:輸出: 方法引用真香!
}
}
說明:obj::print 引用了 obj 對象的 print 方法,等價于 Lambda 表達(dá)式 (msg) -> obj.print(msg)。
3?? 引用某個類的實(shí)例方法:ClassName::instanceMethod
import java.util.function.BiPredicate;
public class ClassInstanceMethodRef {
public static void main(String[] args) {
// 使用方法引用調(diào)用 String 的 equalsIgnoreCase 方法
BiPredicate<String, String> equalsIgnore = String::equalsIgnoreCase;
System.out.println(equalsIgnore.test("java", "JAVA")); // 輸出:true
}
}
說明:String::equalsIgnoreCase 引用了 String 類的實(shí)例方法 equalsIgnoreCase,等價于 Lambda 表達(dá)式 (s1, s2) -> s1.equalsIgnoreCase(s2)。注意,第一個參數(shù) s1 成為方法調(diào)用的對象。
4?? 引用構(gòu)造器:ClassName::new
import java.util.function.Supplier;
class Person {
String name = "默認(rèn)名";
}
public class ConstructorRef {
public static void main(String[] args) {
// 使用方法引用調(diào)用 Person 的無參構(gòu)造器
Supplier<Person> supplier = Person::new;
Person p = supplier.get();
System.out.println(p.name); // 輸出:默認(rèn)名
}
}
說明:Person::new 引用了 Person 類的無參構(gòu)造器,等價于 Lambda 表達(dá)式 () -> new Person()。
?? 方法引用結(jié)合 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 表達(dá)式打印每個名字
names.forEach(name -> System.out.println(name));
// 使用方法引用,效果相同但更簡潔
names.forEach(System.out::println);
}
}
說明:System.out::println 引用了 System.out 對象的 println 方法,等價于 Lambda 表達(dá)式 name -> System.out.println(name)。方法引用使代碼更簡潔,意圖更清晰。
?? 小結(jié)
- 方法引用是 Lambda 表達(dá)式的簡寫形式;
- 可讀性更強(qiáng),代碼更簡潔;
- 常與函數(shù)式接口(如
Function、Consumer、Supplier等)結(jié)合使用; - 常見于 Stream、事件回調(diào)、異步處理等場景。