文章目录

  • 方法引用
  • 1、语法引用符
  • 2、通过对象名引用成员方法
  • 3、通过类名称引用静态方法
  • 4、通过super引用成员方法
  • 5、通过this引用成员方法
  • 6、类的构造器引用
  • 7、数组的构造器引用




方法引用



1、语法引用符

双冒号::为引用运算符,而它所在的表达式被称为方法引用。如果Lambda要表达的函数方案已经存在于某个方法的实现中,那么则可通过双冒号来引用该方法作为Lambda的替代者。

语义分析

如:System.out对象中有一个重载的println方法,其中System.out是已经存在的对象,其中println方法是已经存在的方法,所以有2种写法:

  • Lambda表达式写法:s -> System.out.println(s)
  • 方法引用写法:System.out::println

第一种语义指:拿到参数之后经Lambda之手,继而传给System.out.println方法去处理。

第二种语义指:直接让System.out中的println方法来取代Lambda。

注:Lambda中传递的参数一定是方法引用中的那个方法可以接收的类型,否则会报异常。



2、通过对象名引用成员方法

对象一定要是存在的,不然无法使用。

PrintString.java

@FunctionalInterface
public interface PrintString {
    String print(String str);
}

StringToUppercase.java

public class StringToUppercase {
    public String stringToUppercase(String str){
        return str.toUpperCase();
    }
}

StringToUppercaseTest.java

public class StringToUppercaseTest {
    public static void printUppercase(PrintString p){
        System.out.println(p.print("heroC"));
    }
    public static void main(String[] args) {
        StringToUppercase obj = new StringToUppercase();
        // 使用方法引用,实现PrintString接口的print方法,注重方法体,该方法需要返回Stirng类型的数据。
        // 方法体实则是,通过obj对象调用了stringToUppercase方法。而这个方法作为了函数式接口print抽象方法的具体实现。将参数传递进去执行结果。参数可前后推导
        printUppercase(obj::stringToUppercase);
        /*
        printUppercase()方法是使用的函数式接口因此需要实现PrintString中的print方法,又因为给print方法传递了字符串“heroC”
        printUppercase(new PrintString(){
        	@Override
        	String print(String str){
        		obj.stringToUppercase(String str);
        	}
        });
        */
    }
}
// 输出:HEROC



3、通过类名称引用静态方法

PrintString.java

@FunctionalInterface
public interface PrintString {
    String print(String str);
}

StringToUppercase.java

public class StringToUppercase {
    public static String stringToLowercase(String str){
        return str.toLowerCase();
    }
}

StringToUppercaseTest.java

public class StringToUppercaseTest {
    public static void printUppercase(PrintString p){
        System.out.println(p.print("heroC"));
    }
    public static void main(String[] args) {
        // 使用方法引用,实现PrintString接口的print方法,注重方法体,该方法需要返回Stirng类型的数据。
        // 方法体实则是,通过方法名调用了stringToLowercase静态方法。
        // 将参数传递进去执行结果。参数可前后推导
        printUppercase(StringToUppercase::stringToLowercase);
    }
}
// 输出:heroc



4、通过super引用成员方法

使用前提,必须有子父类关系。

PrintInfo.java

@FunctionalInterface
public interface PrintInfo {
    void print();
}

Human.java

public class Human {
    public void printHuman(){
        System.out.println("我是父类Human");
    }
}

Man.java

public class Man extends Human {
    @Override
    public void printHuman() {
        System.out.println("我是子类Man");
    }

    public void method(PrintInfo prin){
        prin.print();
    }

    public void printMethod(){
        // 通过方法引用,调用super父类的printHuman方法
        method(super::printHuman);
    }

    public static void main(String[] args) {
        new Man().printMethod();
    }
}
// 输出:我是父类Human



5、通过this引用成员方法

PrintInfo.java

@FunctionalInterface
public interface PrintInfo {
    void print();
}

Human.java

public class Human {
    public void printHuman(){
        System.out.println("通过this引用打印");
    }

    public void method(PrintInfo prin){
        prin.print();
    }

    public void methodTest(){
        // 调用this中的printHuman方法重写接口的print方法
        method(this::printHuman);
    }

    public static void main(String[] args) {
        new Human().methodTest();
    }
}
// 输出:通过this引用打印



6、类的构造器引用

使用类名::new的格式表示

PersonInterface.java

@FunctionalInterface
public interface PersonInterface {
    Person func(String name);
}

Person.java

public class Person {
    private String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}

Test.java

public class Test {
    public static void method(PersonInterface per){
        Person person = per.func("heroC");
        System.out.println(person);
    }

    public static void main(String[] args) {
        // 将PersonInterface的func方法重写了,调用了Person构造器,因为传递了heroC字符串
        // 会自动调用带参构造器
        method(Person::new);
    }
}
// 输出:Person{name='heroC'}



7、数组的构造器引用

如:int[]::new

ArrayInterface.java

public interface ArrayInterface {
    int[] createArray(int len);
}

ArrayImp.java

public class ArrayImp {
    public static int[] method(int len, ArrayInterface arr){
        return arr.createArray(len);
    }

    public static void main(String[] args) {
        // 数组构造器引用
        System.out.println( method(10, int[]::new).length );
    }
}
// 输出:10