方法引用(::
)
双冒号(::
)运算符在Java 8 中被称为方法引用(method reference)
,方法引用是与 lambda 表达式相关的一个重要特性。方法引用提供了一种不执行方法的方法,它需要由兼容的函数式接口构成的目标类型上下文。
使用 lambda 表达式会创建匿名方法, 但有时候我们想只调用一个已经存在的方法(不做其它), 这就有了方法引用!方法引用其实是一些 lambda 表达式的简化。
函数式接口
函数式接口是指:有且仅有一个抽象方法的接口。
函数式接口,即适用于函数式编程场景的接口。Java 中的函数式编程体现就是 Lambda,所以函数式接口就是可以适用于 Lambda 使用的接口。只有确保接口中有且仅有一个抽象方法,Java 中的 Lambda 才能顺利地进行推导。
定义一个函数式接口很简单,只要确保接口中有且仅有一个抽象方法即可,如下:
修饰符 interface 接口名称 {
public abstract 返回值类型 方法名称(可选参数信息);
// 其他非抽象方法内容
}
接口中抽象方法的 public abstract 修饰符可以省略,一个函数式接口示例如下:
public interface Test {
void method();
}
Java 8 中方法引用的语法:
- 静态方法引用(static method)语法:classname::methodname 例如:Person::getAge;
- 对象的实例方法引用语法:instancename::methodname 例如:System.out::println;
- 对象的超类方法引用语法: super::methodname;
- 类构造器引用语法: classname::new 例如:ArrayList::new ;
方法引用示例
简化 lambda 表达式
public class Test {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
//使用lambda表达式
list.forEach(x -> System.out.println(x));
System.out.println("----------------");
//使用“::”方法引用
list.forEach(System.out::println);
}
}
结果:
a
b
c
----------------
a
b
c
静态方法引用
public class Test {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
// 静态方法引用
list.forEach(Test::print);
}
public static void print(String s){
System.out.println(s);
}
}
对象的实例方法引用
public class Test {
public Test(){}
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
// 对象的实例方法引用
list.forEach(new Test()::print);
}
public void print(String s){
System.out.println(s);
}
}
对象的超类方法引用语法
public class Test extends SuperTest{
public Test(){}
void test(){
List<String> list = Arrays.asList("a", "b", "c");
// 对象的超类方法引用语法
list.forEach(super::print);
}
public static void main(String[] args) {
new Test().test();
}
}
class SuperTest{
void print(String s){
System.out.println(s);
}
}
类构造器引用语法
public class Test{
public static void main(String[] args) {
// 类构造器引用语法
InterfaceExample interfaceExample = Test::new;
Test test = interfaceExample.create();
}
}
interface InterfaceExample{
Test create();
}