方法引用

方法引用

  • 双冒号::式引用运算符,其所在的表达式被称为方法引用

  • 当对象和方法已经存在时,可以使用方法引用优化Lambda表达式

  • 分析:

    下面程序中Lambda表达式的目的:打印参数传递的字符串
    printstring中把参数s传递给了System.out对象,调用out中的方法println对字符串输出
    因为System.out对象和println已经存在,所以可使用方法引用优化表达式
    使用System.out直接引用println方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@FunctionalInterface
public interface DemoInterface {
void print(String s);//打印字符串的抽象方法
}

public class DemoPrintable {
public static void printstring(DemoInterface p){
p.print("HelloWorld");
}
public static void main(String[] args) {
printstring((s)->{
System.out.println(s);
});
printstring(System.out::println);
}
}

实现引用成员方法

  • 自定义一个类MethodReObject
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MethodReObject {
String name;
public MethodReObject() {
}
public MethodReObject(String name) {
this.name = name;
}
public String getName() {
return name;
}
//定义一个成员方法,传递字符串,把字符串大写输出
public void printUppercase(String s){
System.out.println(s.toUpperCase());
}
public static int calc(int a,int b){ //静态成员方法
return a+b;
}
public void sayHello(){
System.out.println("Hello");;
}
}

1. 通过对象引用成员方法

  • 定义一个接口DemoInterface,包含一个抽象方法print
  • 在主类中定义printstring方法,参数为接口DemoInterface类型,方法中调用接口的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@FunctionalInterface
public interface DemoInterface {
void print(String s);//打印字符串的抽象方法
}
public class test {
public static void printstring(DemoInterface p){
p.print("hello");
}
public static void main(String[] args) {
printstring((s)->{
MethodReObject mp = new MethodReObject();
mp.printUppercase(s);
});
MethodReObject object = new MethodReObject();
printstring(object::printUppercase);
}
}

2. 通过类名引用静态方法

  • 定义一个函数式接口Calcable,包含抽象方法可以计算两个数的和
  • 在主类中定义方法method1,参数传递Calcable接口,调用其中的给抽象方法
1
2
3
4
5
6
7
8
9
10
11
12
13
@FunctionalInterface
public interface Calcable {
int cal(int a,int b);
}
public class test {
public static int method1(int a,int b,Calcable p){
return p.cal(a,b);
}
public static void main(String[] args) {
int r = method1(1,2,MethodReObject::calc); //通过类名引用静态方法
System.out.println(r);
}
}

3. 通过super和this引用成员方法

  • 如果存在继承关系,当Lambda中需要super调用时,也可以使用方法引用进行替代

  • this代表当前对象,如果需要引用的方法就是当前类中的成员方法,可以使用 this::成员方法 来进行方法引用

    • 定义函数式接口Greetable

    • 定义子类SubReObject 继承 MethodReObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@FunctionalInterface
public interface Greetable {
void greet();
}
public class SubReObject extends MethodReObject{
@Override
public void sayHello() {
System.out.println("hello,i'm hxx");
}
//定义一个方法参数传递函数式接口Greetable
public static void method2(Greetable g){
g.greet();
}
//定义一个方法调用method
public void show(){
method2(()->{
MethodReObject obj = new MethodReObject();//创建父类对象
obj.sayHello();
});
method2(()->{
super.sayHello();
});
method2(super::sayHello);
method2(this::sayHello);//通过this引用本类的方法

}
public static void main(String[] args) {
new SubReObject().show();
}
}

4. 类的构造器引用

  • 构造器引用使用 类名称::new 的格式表示
  • 定义函数式接口ObjectBuilder ,创建一个MethodReObject对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@FunctionalInterface
public interface ObjectBuilder {
//创建一个MethodReObject对象
MethodReObject BuilderObject(String name);
}

public class test {
public static void method2(String name,ObjectBuilder ob){
MethodReObject object = ob.BuilderObject(name);
System.out.println(object.getName());
}
public static void main(String[] args) {
method2("hxx",(String name)->{
return new MethodReObject(name);
});
method2("hxx",MethodReObject::new);//构造器引用
}
}

5. 数组的构造器引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@FunctionalInterface
public interface ArrayBuilder {
//定义一个创建int类型数组的方法,参数传递数组的长度,返回创建好的int类型数组
int []builderArray(int len);
}
public class test {
public static int[] creatArray(int len,ArrayBuilder ab){
int[] array = ab.builderArray(len);
return array;
}
public static void main(String[] args) {
//调用creatArray方法
int[] array = creatArray(3, len -> {
return new int[len];
});
//int[]引用new
int[] array1 = creatArray(3, int[]::new);
}
}