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 } };
摘自:https://blog.csdn.net/Feng_dian/article/details/101350440