Lambda 表达式的类型, 也被称为目标类型(targer type),Lambda 表达式的目标类型必须是 "函数式接口(functional interface)". 函数式接口代表只包含一个抽象方法的接口. 函数式接口可以包含多个默认方法, 类方法, 但只能声明一个抽象方法.
如果采用匿名内部类的语法来创建函数式接口, 则只需要实现一个抽象方法, 在这种情况下即可采用 Lambda 表达式来创建对象. 该表达式创建出来的对象的目标类型就是这个函数式接口.
Java 8 专门为函数式接口提供了 @FunctionalInterface 注解, 该注解通常放在接口定义前面, 对程序功能没有任何作用, 它用于告诉编译器执行更严格的检查 -- 检查该连接口必须是函数式接口, 否则编译器就会报错.
由于 Lambda 表达式的结果就是被当成对象, 因此程序中完全可以使用 Lambda 表达式进行赋值, 例如:
- Runnable r = ()-> {
- for(int i = 0; i <100; i++){
- //coding here
- }
- };
Runnable 接口中只包含一个无参数的方法, Lambda 表达式代表的匿名方法实现了 Runnable 接口中唯一的, 无参数的方法, 因此 Lambda 表达式创建了一个 Runnable 对象
Runnable 是 Java 本身提供的一个函数式接口
从上面代码可以看出, Lambda 表达式实现的是匿名方法 -- 因此它只能实现特定函数式接口中的唯一方法. 这意味着 Lambda 表达式有如下两个限制
Lambda 表达式的目标类型必须是明确的函数式接口.
Lambda 表达式只能为函数式接口创建对象. Lambda 表达式只能实现一个方法, 因此它只能为只有一个抽象方法的接口 (函数式接口) 创建对象.
如下的代码会报错
- Object obj = ()-> {
- for(int i = 0; i <100; i++){
- //coding here
- }
- };
这段代码与上一段几乎完全相同, 只是此时 Lambda 表达式赋值给 Object 对象
不兼容的类型: Object 不是函数式接口
从该错误信息可以看出, Lambda 表达式的目标类型必须是明确的函数式接口. 上面代码将 Lambda 表达式赋值给 Object 变量, 编译器只能确定该 Lambda 表达式的类型为 Object, 而 Object 并不是函数式接口, 因此报错.
为了保证 Lambda 表达式的目标类型是一个明确的函数式接口, 可以有如下三种常见方式.
将 Lambda 表达式赋值给函数式接口类型的变量
将 Lambda 表达式作为函数式接口类型的变量
使用函数式接口对 Lambda 表啊是进行强制类型转换
- Object obj = (Runnable)()-> {
- for(int i = 0; i < 100; i++){
- //coding here
- }
- };
来源: http://www.bubuko.com/infodetail-2994203.html