
上QQ阅读APP看书,第一时间看更新
3.2.1 Java 8的Lambda
在Java 8之前,我们使用Thread可能是这样的:

Java 8之后开始支持Lambda表达式,于是我们可以这样写:
new Thread(()->System.out.println("test")).start();
从Runnable的源码可以发现,它使用了@FunctionalInterface,@FunctionalInterface是Java 8为函数式接口引入的一个新的注解。表明该接口是函数式接口,只包含唯一一个抽象方法。任何可以接收一个函数式接口实例的地方都可以使用Lambda表达式。

Java 8的Lambda表达式是一个SAM(Single Abstract Method)类型。因为Java没有像Kotlin那样拥有函数类型,所以需要借助SAM类型来实现Lambda表达式。
Java 8的Lambda语法:
(参数列表) -> {函数体}
如图3-3所示,Java的Lambda有多种形式。对于无参的Lambda表达式:
() -> {函数体}

图3-3 Java 8的Lambda形式
对于单个参数的Lambda表达式:
(x) -> {函数体}
它可以简化为:
x -> {函数体}
对于多个参数的Lambda表达式:
(x,y,z) -> {函数体}
如果函数体只有一行代码,则可以省略函数体的大括号。另外,对于参数列表,由于Java的编译器可以进行类型推断,因此不需要声明参数的类型。
在Java 8中,Lambda的创建是通过字节码指令invokedynamic来完成的,减少了类型和实例的创建消耗。在Java 8之前,我们使用匿名类,但是匿名类需要创建新的对象。