更多技术交流,请搜索关注公众号—员说。
写在前面
lambda表达式是一个匿名函数。在Java 8中,它和函数式接口一起,共同构建了函数式编程的框架。
lambda表达式乍看像是匿名内部类的一种语法糖,但实际上,它们是两种本质不同的事物。匿名内部类本质是一个类,只是不需要程序员显示指定类名,编译器会自动为该类取名。而 lambda 表达式本质是一个函数,当然,编译器也会为它取名。在JVM层面,匿名内部类对应的是一个 class 文件,而 lambda 表达式对应的是它所在主类的一个私有方法。
lambda 表达式可以在函数体中引用外部的变量,从而实现了闭包。但 Java 对进入闭包的变量有 final 的限制,当然我们可以绕开这个限制。
本文的示例代码可从gitee上获取:
Java中的函数式编程示例代码https://gitee.com/cnmemset/javafphttps://gitee.com/cnmemset/javafp
lambda表达式与匿名内部类
lambda表达式可以用来简化某些匿名内部类(Anonymous Inner Classes)的写法,但仅限于对函数式接口的简写。
无参的函数式接口
以最常用的Runnable接口为例:
在Java 7中,如果需要新建一个线程,使用匿名内部类的写法是这样:
public static void createThreadWithAnonymousClass() {
// Runnable 是接口名。我们通过匿名内部类的方式,构造了一个 Runnable 的实例。
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread is running");
}
});
t.start();
}
使用匿名内部类的一个重要目的,就是为了减轻程序员的代码负担,不需要额外再定义一个类,而且这个类是一个一次性的类,没有太多的重用价值。但是,我们会发现,这个对象看起来也是多余的,因为我们实际上并不是要传入一个对象,而只是想传入一个方法。
在Java 8中,因为 Runnable 接口是一个函数式接口(只有一个抽象方法的接口都属于函数式接口),因此我们可以用lambda表达式来简化匿名内部类的写法:
public static void createThreadWithLambd