jdk8-方法引用

后端 / 笔记 / 2021-09-21

什么是方法引用?

简化lambda表达式,使代码更精简强大。
方法引用本质上就是lambda表达式中直接引用的方法

遵循规范

  • 方法参数列表,返回类型 要与 函数接口参数列表与返回值类型必须保持一致

image.png

使用步骤

  1. 首先写个lambda表达式
  2. 然后写个和lambda表达式体内参数返回值类型一致的方法
  3. 最后 InterfaceName in = ObjectName::method

注意方法引用不需要加括号哦~

静态方法引用

类名::静态方法名称

package jdk8.method;

@FunctionalInterface
public interface MessageInterface {
    void message(String s);
}

package jdk8.method;

public class StaticMethodIntro {
    public static void main(String[] args) {
        // 静态方法引用

        // 首先写个lambda表达式
        ((MessageInterface) s -> System.out.println(s)).message("Hello,World!");

        // 静态方法替换lambada表达式
        ((MessageInterface) s -> staticMessage(s)).message("Hello,World!");

        // 睁大眼 静态方法引用
        MessageInterface messageInterface = StaticMethodIntro::staticMessage;
        messageInterface.message("hello,world!");
    }

    public static void staticMessage(String msg) {
        System.out.println(msg);
    }
}

对象方法引用

类名:对象方法名称
如果接口方法体第一个参数为 当前对象 那么可以直接引用非静态方法,前提是要满足方法引用的规则。

image.png

package jdk8.method;


interface Service {
    String get(ObjectMethodIntro that);
}

public class ObjectMethodIntro {
    public static void main(String[] args) {
        // 首先写个lambda表达式
        Service service = (that) -> that.getStr();
        System.out.println(service.get(new ObjectMethodIntro()));

        // 方法引用
        Service service1 = ObjectMethodIntro::getStr;
        System.out.println(service1.get(new ObjectMethodIntro()));
        /**
         * 思考:这里的 getStr 方法不是静态的为什么还能调用
         * ObjectMethodIntro::getStr <==> (that) -> that.getStr();
         * 是相互等价的
         * 当接口方法参数出现对象本身时 可以使用这种方法
         */
    }


    public String getStr() {
        return "中秋了,大抵是到了该寻一个姑娘的年纪了,近来夜里冷的厉害,特别是心里,凉的出奇,两床被子面对这寒冬的挑衅,也显得有些许吃力了,或许只有心仪姑娘的照料,才能让我感到温暖罢了";
    }
}

中秋了,大抵是到了该寻一个姑娘的年纪了,近来夜里冷的厉害,特别是心里,凉的出奇,两床被子面对这寒冬的挑衅,也显得有些许吃力了,或许只有心仪姑娘的照料,才能让我感到温暖罢了
中秋了,大抵是到了该寻一个姑娘的年纪了,近来夜里冷的厉害,特别是心里,凉的出奇,两床被子面对这寒冬的挑衅,也显得有些许吃力了,或许只有心仪姑娘的照料,才能让我感到温暖罢了

实例方法引用

new 对象 对象实例::方法引用

package jdk8.method;

interface MessageSupplier {
    String get();
}


public class InstanceMethodIntro {
    public static void main(String[] args) {
        // 首先写个lambda表达式
        MessageSupplier ms = () -> "我怎么还没女朋友";
        System.out.println(ms.get());

        // 然后用实例方法代替方法体
        InstanceMethodIntro instanceMethodIntro = new InstanceMethodIntro();
        MessageSupplier ms1 = () -> instanceMethodIntro.objGet();
        System.out.println(ms1.get());

        // 最后 直接将 方法赋值给接口
        MessageSupplier ms2 = instanceMethodIntro::objGet;
        System.out.println(ms2.get());
    }

    public String objGet() {
        return "我怎么还没obj";
    }
}
我怎么还没女朋友
我怎么还没obj
我怎么还没obj

构造方法引用

类名::new
这里调用的是默认的无参构造函数

package jdk8.method;


import java.util.function.Supplier;

interface WrapperSupplier {
    StringWrapper get();
}

class StringWrapper {
    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    private String str;


    public StringWrapper() {
    }


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

public class ConstructMethodIntro {
    /**
     * 构造函数引用
     * - 参数列表 返回值类型要一致
     *
     * @param args
     */
    public static void main(String[] args) {
        // 首先写个lambda表达式
        WrapperSupplier ws = () -> new StringWrapper();
        System.out.println(ws.get());
        // 然后 构造方法引用 调用默认无参构造
        WrapperSupplier ws2 = StringWrapper::new;
        System.out.println(ws.get());
        
        // 用构造方法引用实现一个构建者
        StringWrapper wrapper = builder(StringWrapper::new);
        wrapper.setStr("少年遥想得山田,赶在天黑日落前");
        System.out.println(wrapper.getStr());

    }


    public static <T> T builder(Supplier<T> sup) {
        return sup.get();
    }
}