标签:函数 com 就是 java 符号 表达 约束 div 需要
在上一篇文章《Java里的函数式接口》介绍了关于函数式接口的内容,那么本文基于函数式接口来继续学习lambda表达式。
Runnable runnable = () -> System.out.println("Runnable Instance");
这种使用箭头符号->分开参数列表和方法体的语法就是lambda表达式。在Java 里没有和lambda 表达式对应的类定义或者代码库,lambda表达式总是在定义后赋值给某个函数式接口类型变量。
一个 lambda表达式的参数列表声明和方法实现必须和所赋值的函数式接口函数中的抽象方法匹配。关于lambda表达式和函数式接口之间的关系还有以下注意点:
在lambda表达式里可以使用上下文中的变量,但是和匿名类中使用上下文变量一样的限制,要求变量必须是final的。
然而在Java8里,也可以不明确的加上final,只需要该变量是一种“形式final”即可。例如以下代码会通过编译并正常运行:
String message = "Message"; Runnable runnable = () -> System.out.println(message); new Thread(runnable).start();
message变量并没有加上关键字final,但是很明显它被初始化之后没有对它进行任何操作,所以“显然”它肯定是“不可变”的,所以可以在lambda 表达式里使用。但是以下代码就不能通过编译:
String message = "Message"; message = "Message2"; Runnable runnable = () -> System.out.println(message); new Thread(runnable).start();
在message初始化之后,又进行了一次赋值操作,明显不符合一个final变量只能赋值一次的约束,所以lambda表达式里不能使用。
关于在Java8里引入的这种新特性,到底是什么实现的呢?我们可以编译代码之后查看class文件,就会发现上述代码变成了以下样子:
final String message = "Message"; Runnable runnable = () -> { System.out.println(message); }; (new Thread(runnable)).start();
编译器自动给message加上了final关键字。
lambda表达式不单独存在和使用,它总是从上下文中推导参数类型和自己的类型,可以把lambda表达式赋值给符合条件的函数式接口类型变量,也可以把它传递给接受符合条件的函数式接口类型的方法里。通过lambda表达式,我们可以真的做到将代码块作为变量一样使用。
标签:函数 com 就是 java 符号 表达 约束 div 需要
原文地址:https://www.cnblogs.com/anivia/p/10064012.html