匿名内部类、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);
}