浅析 Employee::new / String[]::new 是什么意思?Java8新特性-方法引用、构造器引用、数组引用的了解及使用

一、方法引用

  若Lambda体中的内容已经有方法实现过了,我们可以使用方法引用,使用方法引用的时候需要保证引用方法的参数列表和返回值类型与我们当前所要实现的函数式接口方法的参数列表和返回值类型保持一致。方法引用是Lambda表达式的另外一种表现形式。

  主要有 3 种语法格式:

(1)对象 :: 实例方法名

public void test1() {
    Consumer<String> con = (x) -> System.out.println(x);
    con.accept("Hello World!");

    PrintStream ps = System.out;// 返回一个PrintStream对象
    // System.out.println(x)在PrintStream的println方法中已经实现,可以使用方法引用
    Consumer<String> con1 = ps::println;
    con1.accept("Hello Lambda!");

    Consumer<String> con2 = System.out::println;//匿名对象方法引用
    con2.accept("Hello Lambda Method!");
}

(2)类 :: 静态方法名

public void test2() {
    Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
    com.compare(1, 2);

    // 使用方法引用的方式
    Comparator<Integer> com1 = Integer::compare;
    com1.compare(1, 2);
}

(3)类 :: 实例方法名

  前提:第一个参数是实例方法的调用者,第二个参数是实例方法的参数

  注意:

  1、Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保存一致

  2、若Lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用 ClassName::method  -  类 :: 实例方法名

    //类::实例方法名
    @Test
    public void test4(){
        BiPredicate<String, String> bp = (x, y) -> x.equals(y);
        boolean bool = bp.test(new String("huang"),"huang");
        System.out.println(bool);

        //前提:第一个参数是实例方法的调用者,第二个参数是实例方法的参数
        //例如 x 是equal方法的调用者,y是实例方法的参数
        BiPredicate<String,String> bp2 = String::equals;
        bool = bp2.test("huang","huang");
        System.out.println(bool);
    }

二、构造器引用

  语法格式:ClassName::new

  调用哪个构造器取决于函数式接口中的方法形参的定义,Lambda会自动根据接口方法的定义推断你要调用的构造器,也就是说需要调用的构造器的参数列表要与函数式接口中的抽象方法的参数列表保持一致

    //构造器引用
    @Test
    public void test5(){
        Supplier<Employee> sup = ()-> new Employee();
        Employee emp = sup.get();
        //构造器引用:根据参数列表自动匹配构造器
        Supplier<Employee> sup2 = Employee::new;
        emp = sup2.get();
        System.out.println(emp);
    }

    @Test
    public void test6(){
        Function<Integer,Employee> func = x -> new Employee(x);
        Employee emp = func.apply(10);
        System.out.println(emp);

        Function<Integer,Employee> func1 = Employee :: new;
        emp = func1.apply(10);
        System.out.println(emp);

       // BiFunction<Integer, Integer, Employee> bf = Employee::new;编译错误,没有两个Integer构造器
    }

  示例1:此时会调用Employee的无参构造器,因为Supplier接口的抽象方法没有入参

  示例2:此时Employee中需要一个:一个入参的构造器

  示例3:当需求 2 个 入参的构造器时,会编译错误。因为没有默认 2 个参数的构造器。

三、数组引用

  同构造器引用,语法格式为 Type[] :: new

public void test5() {
    Function<Integer, String[]> fun = (x) -> new String[x];
    fun.apply(10);

    // 数组引用
    Function<Integer, String[]> fun1 = String[]::new;
    fun1.apply(20);
}

 

posted @ 2021-09-18 19:03  古兰精  阅读(1444)  评论(0编辑  收藏  举报