不灭的焱

革命尚未成功,同志仍须努力下载JDK17

作者:php-note.com  发布于:2022-05-03 19:30  分类:Java基础  编辑

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