夏眠鱼

Jul 10, 2016

Java Lambda

背景

Lambda 表达式支持将代码块作为方法参数,以更简洁的方式创建函数式接口的实例。主要作用是代替匿名内部类的烦琐语法。

函数式接口

Lambda 表达式的类型,也被成为目标类型(target type),必须是函数式接口(functional interface)。函数式接口是指可以包含多个默认方法(default 关键字修饰)、类方法,但只能包含一个抽象方法的接口。

Java 8 为函数式接口提供了 @FunctionalInterface 注解,作用于类型,指定该接口必须是函数式接口。

Lambda 表达式语法

Lambda 表达式语法由形参列表、箭头和代码块三部分构成:

形参列表 箭头 代码块
(int x, int y) -> x + y

形参列表

形参列表允许省略形参参数。如果形参列表中只有一个参数,可以省略圆括号。

箭头

->:由英文中划线和大于号组成

代码块

  • 只有一条语句时,可省略代码块的花括号;
  • 只有一条 return 语句时,可省略 return 关键字。

代码示例

1
2
3
4
5
6
7
8
9
10
11
// Anonymous Runnable
Runnable run1 = new Runnable() {

@Override
public void run() {
System.out.println("hello world1");
}
};

// Lambda Runnable
Runnable run2 = () -> System.out.println("hello world2");

Lamba 与匿名内部类的异同

相同点

  • 都可以直接访问 effectively final 局部变量、外部类的成员变量(实例变量和类变量);
  • 都可以直接调用从接口中继承的默认方法

不同点

  • 匿名内部类可以为任意接口创建实例,不管接口包含多少个抽象方法,只要匿名内部类实现所有的抽象方法即可,但 Lambda 表达式只能为函数式接口创建实例;
  • 匿名内部类可以为抽象类甚至普通类创建实例,但 Lambda 表达式只能为函数式接口创建实例;
  • 匿名内部类实现的抽象方法的方法体允许调用接口定义的默认方法,但 Lambda 表达式的代码块中不允许调用接口中定义的默认方法。

参考

OLDER > < NEWER