方法引用是 Java 中简化 Lambda 表达式的一种方式,通过类名和方法名定位到指定的方法,使用起来非常灵活。方法引用可以在已有 Lambda 表达式的基础上忽略掉参数声明和传参的过程。参数声明和传参的过程则是交给了底层编译器。
方法引用使用前提: 1,方法引用的对象必须是一个函数式接口。2,已有的 Lambda 表达式仅调用了一个方法,且该方法已被实现。
方法引用主要分为以下几种:
- 实例方法引用
- 对象方法引用
- 静态方法引用
- 数组引用
- 构造方法引用
我会在下文分别讲一下它们如何使用。
1,实例方法引用
假如我们现在有一个类,echo 方法接受一个 Consumer 函数式接口方法参数,和一个字符串参数,调用 Consumer 消费字符串参数。
public class ObjDemo { //
public void echo(Consumer<String> consumer, String message) { //
consumer.accept(message);
}
}
然后我们来看看使用方法引用与不使用方法引用的区别。
public class Main { //
public static void main(String[] args) { //
ObjDemo objDemo = new ObjDemo();
// 不使用方法引用
objDemo.echo(s -> { //
System.out.println(s);
}, "hello world ~");
// 使用方法引用
objDemo.echo(System.out::println, "hello world ~");
}
}
可以看到,使用方法引用后,参数声明和传参的过程被忽略了。
然后我前面也讲到了,方法引用使用形式为: 对象名: 方法名 或类名: 方法名。我们先来看看原先的 Lambda 表达式:
s -> { //
System.out.println(s);
}
s 和 (s) 是不是就是参数声明和传参的过程?因此忽略。println 是一个方法,然后再把实例名和方法名之间用引用运算符 ”::” 拼接,得到 System.out::println
被忽略掉的参数列表和传参的过程则是交给了编译器代替我们去完成这些操作。
2,对象方法引用和类静态方法引用
由于内容不是很复杂,同时为了节省时间,这两个引用我就一起讲了。
public class ObjDemo { //
public void getInfo(Supplier<String> supplier) { //
supplier.get();}
}
对象方法引用的使用例子:
public class Main { //
public static void main(String[] args) { //
Student student = new Student("Lujia", 46, "男");
ObjDemo objDemo = new ObjDemo();
// 不使用方法引用
objDemo.getInfo(() -> { //
return student.getName();});
// 使用方法引用
objDemo.getInfo(student::getName);
}
}
静态方法引用则是: 类名:: 方法名,大家可以自己尝试一下。
3, 构造方法引用
构造方法引用的使用形式: 类名:new。支持无参构造和有参构造。
假如我们现在有一个方法,方法接受一个 Function 函数式接口参数,将参数 2 字符串转换成 ObjDemo2 对象。
public class ObjDemo { //
public ObjDemo2 getInfo(Function<String, ObjDemo2> function, String s) { //
return function.apply(s);
}
}
public class Main {//
public static void main(String[] args) {//
ObjDemo objDemo = new ObjDemo();
// 不使用方法引用
objDemo.getInfo((s1) -> {return new ObjDemo2(s1);
}, "lujia");
// 使用方法引用
ObjDemo2 lujia = objDemo.getInfo(ObjDemo2::new, "lujia");
}
}
4,数组引用
数组引用的使用形式: 数据类型[]:new。下面给大家看一下使用例子。
public class ObjDemo { //
public void demo(Function<Integer, String[]> function, Integer length) { //
function.apply(length);
}
}
demo 给定一个 length,然后创建一个指定长度的字符串数组。
public class Main { //
public static void main(String[] args) { //
ObjDemo objDemo = new ObjDemo();
// 不使用方法引用
objDemo.demo(length -> { //
return new String[length];
}, 10) ;
// 使用方法引用
objDemo.demo(String[]::new, 10) ;
}
}
