jdk8 方法引用&lambda&匿名内部类

匿名内部类、lambda和方法引用其实是相通的,从匿名内部类到lambda到方法引用是一个进化的过程,是一个简化的过程,更加是一个从抽象的过程。作用都是实现接口方法,换句话说就是实现接口;只是这个接口只有一个抽象方法。

匿名内部类省去了实现类,直接new 接口名(){...} 没有实现类名,实际就是实现且创建了一个接口对象。

lambda表达式省去了new 接口名;简化为() ->{...} 实际也是实现且创建一个接口对象。一个方法的参数括号中是否可以使用lambda表达式,取决于这个方法的参数类型:是否是一个函数式接口(只有一个抽象方法可以有多个default方法的接口),构造方法也同理。

方法引用省去了lambda,将接口方法实现的内容封装到具体方法,将方法作为接口实现,实际也是实现且创建一个接口对象。只是更加抽象,只能看到接口方法内部实现(调用的这个方法就是具体实现)。

上代码:

import org.junit.Test;

public class T01 {

    @Test
    public void t1(){
        //1、方法引用(静态)
        exec(T01::rec); //public static void rec(String s){...} 很明显是一个静态方法引用。
                        //静态方法引用:exec()如果有参数(实际是accept()有参数)会把参数当方法rec()的实参;
                        //rec()中的参数就是accept()传递过去的;rec和accept要么都有参数,要么都没有参数,
                        //如果rec没有参数accept有参数或者rec有参数accept没有参数,那么方法引用都会语法错误
        //2、lambda表达式
        exec(s->{T01.rec(s);});//void accept(String s); lambda表达式参数和抽象方法参数相对应
        //3、匿名内部类
        exec(new Interf() {//普通的匿名内部类
            @Override
            public void accept(String s) {
                T01.rec(s);
            }
        });
        //4、构造方法
        Interf interf = (s)->{};//本质上和exec(s->{T01.rec(s);});是一样的,()->{}本身就是带实现的对象;
                                //相当于new一个对象,不同点只是将对象赋给了变量。而非当做方法参数传递。
    }

    public void exec(Interf interf){
        interf.accept("ccc");
        System.out.println("bbb");
    }

    public static void rec(String s){
        System.out.println(s);
        System.out.println("aaa");
    }
}


interface Interf{
    void accept(String s);
}

猜你喜欢

转载自blog.csdn.net/FromTheWind/article/details/85143502