Lambda表达式,可以像下面这样,在其函数体内访问外部的变量。
public class Closure {
private String abc = "abc";
public String joinStr(String str, UnaryOperator<String> unaryOperator){
return unaryOperator.apply(str);
}
public void useJoinStr(String str){
String prefix = "log:";
String result = joinStr(str,s -> {
return prefix+s;
});
System.out.println(result);
}
public static void main(String[] args) {
Closure closure = new Closure();
closure.useJoinStr("this is a test");
}
}
在函数useJoinStr中,调用joinStr,传入字符串的同时,传递一个Lambda,这个Lambda完成一个工作,就是给字符串增加一个“log:”的前缀。这里前缀定义为函数useJoinStr的局部变量,执行main函数得到结果
log:this is a test
这是我们预期的结果,但是要注意一点,Java编译器要求,Lambda引用的外部变量如果是局部变量,该变量应该是,或实际意义上是final的,也就是该变量不能被改变。如果我们在prefix定义之后修改变量的内容,会引起编译错误,无论在使用前还是使用后
例如:
public void useJoinStr(String str){
String prefix = "log:";
prefix = "loog:";
String result = joinStr(str,s -> {
return prefix+s;
});
System.out.println(result);
}
这里在定义完prefix后,又修改它的值,编译直接就报错了,不允许这样的代码,也可以将该变量修饰为final的。这是Lambda对访问外部的局部变量的要求,使用时需要注意。
但是,Lambda对于使用实例变量和静态变量是没有限制的,下面的代码是有效的。
public void useJoinStr(String str){
final String prefix = "log:";
abc = "log:";
String result = joinStr(str,s -> {
return abc+s;
});
System.out.println(result);
}
这里,修改了对象的私有变量abc,并在lambda中使用该变量,程序可以正常编译,并得到正确的结果。
原文:https://www.cnblogs.com/saint-lxf/p/12775625.html