携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
方法引用介绍
方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法。
方法引用提供了一种引用而不执行方法的方式。方法引用是一种更简洁易懂的 Lambda 表达式。
引用的符号是 ::,其语法形式如下所示:
类名 :: 方法名
⭐ 注意:在使用方法引用时,只需要写方法名,不需要写小括号。
本质上,方法引用是 Lambda 表达式的一种简化形式,请看以下程序。
@FunctionalInterface
interface MyInterface{
void method(Supplier<Double> s) ;
}
public class TestMethodRef {
void methodLambda(MyInterface mi) {
// Lambda表达式
mi.method(() -> Math.random());
}
}
仔细观察 mi.method() 方法的输入参数,不难发现 () -> Math.random() 中左右两端的 () 和箭头符号 -> 在程序中并没有什么实际的作用,省略的具体办法就是使用方法引用。
如下程序中的 methodMethodRef() 就是使用方法引用对 methodLambda() 的等价实现。
void methodRef(MyInterface mi) {
// 方法引用
mi.method(Math::random);
}
方法引用的必要条件和类型
从上面可以看出来,方法引用对lambda进行了简化,那么是否所有的 Lambda 表达式都可以使用方法引用进行简化?
答案是:不是所有都能,使用方法引用必须满足:Lambda 所重写方法的参数列表,必须与所引用方法的参数列一致(或可兼容)。
在 TestMethodRef 代码中,Lambda 表达式重写的是 Supplier<Double> 接口中的 Double get() 方法,该方法的参数列表为空;引用的方法 Math.random() 中的参数列表也是空。二者的参数列表相同,因此可以使用方法引用进行简化。
常见的方法引用有五种类型,如下表所示:
| 方法引用的类型 | 示 例 |
|---|---|
| 引用静态方法 | 类名 :: 静态方法名 |
| 引用某个对象的实例方法 | 对象名 :: 非静态方法 |
| 引用类中的实例方法 | 类名 :: 非静态方法 |
| 引用构造方法 | 类名:: new |
| 引用数组 | 元素类型[] :: new |
可以发现, TestMethodRef 代码中使用的 Math::random 左侧的 Math 是类名,右侧的 random 是静态方法的名字,因此这种写法就是 “引用静态方法” 类型的方法引用。