今天给大家分享一个JDK8中的新特性双冒号:”::“,双冒号“::”就是 Java 中的方法引用,是Java 8中的Lambda表达式写法之一,一种执行方法的方法。
在一定程度上简化了我们Java开发的冗余代码。
双冒号(::)使用场景一般有如下6种:
类型 | 引用语法 | 案例 |
---|---|---|
引用静态方法 | 类名::静态方法名 | Integer::parseInt |
引用特定对象实例方法 | 对象::静态方法名 | System.out::println |
引用特定类型的任意对象的实例方法 | 特定类型::实例方法名 | String::compareToIgnoreCase |
引用超类(父类)的实例方法 | supre::方法名 | supre::fun |
引用类构造方法 | 类名::new | ArrayList::new |
引用数组构造方法 | 数组类型[]::new | String[]::new |
上面的内容太过于官方,下面我们简单看两个小例子:
1. Lambda表达式表达式:
person -> person.getName();
可以替换成:
Person::getName
2. Lambda表达式表达式:
() -> new HashMap<>();
可以替换成:
HashMap::new
在实际的开发中,我们可能还会遇到很多使用双冒号调用方法的操作
public class Test07 {
public static void a(){
System.out.printf("a1");
}
public static void a(String s){
System.out.printf(s);
}
public static void main(String[] args) {
Runnable runnable=Test07::a;
runnable.run();
}
}
这个时候大家能看出调用的是一个a方法吗,我们直接运行一下看一下结果:
说明Runnable对应的是无参的方法a,这是为什么呢?
原因就在于Runnable,追踪到它的原码不难发现它是一个函数式的接口
里面只有一个无参的run方法,这个方法对应到Runnable runnable=Test07::a就是无参的方法a
如果我们想要使用有参的方法a,那么该使用什么呢?
public class Test07 {
public static void a() {
System.out.printf("a1");
}
public static void a(String s) {
System.out.printf(s);
}
public static void main(String[] args) {
Consumer<String> consumer=Test07::a;
consumer.accept("调用有参的方法a");
}
}
通过其源码也可以发现,Consumer也是一个函数式接口,里面提供了一个有参的accept方法,这个方法对应到Test07::a就是有参的方法a,执行之后,可以看到结果如下:
看到这儿大家应该对什么是方法引用有了一些认知,其本质就是Runnable或Consumer来指向一个具体的方法,至于该使用哪一个就要看指向的方法是否有参数
可能有人就会有疑虑,因为我们Consumer的accept只能接收一个方法,那么所引用的方法也就只能对应一个参数,如果是多个参数怎么办,像下面的方法:
public static void a(String s1,String s2) {
System.out.printf(s1+s2);
}
JDK内置了很多默认的函数式接口,比如BiConsumer
public static void main(String[] args) {
BiConsumer<String,String> biConsumer=Test07::a;
biConsumer.accept("测试","数据");
}
可以看到它可以接收两个参数,如果参数大于等于两个,建议将参数封装为一个对象,通过对象去传参
上面的内容均是无返回结果的,因为不管是Runnable的run方法还是Consumer的accept方法,均无返回值,如果我们需要返回值则可以使用Callable
通过源码不难发现Callable也是一个函数式接口,里面提供了一个无参的call方法,并且提供了返回值
public class Test07 {
public static String b(){
return "b";
}
public static void main(String[] args) throws Exception {
Callable<String> runnable=Test07::b;
String s=runnable.call();
System.out.printf(s);
}
}