报错Case
Lambda表达式对dest添加对象,后续对dest变量修改(非内容修改),报错!
List<String> dest = new ArrayList<>();
List<String> src = new ArrayList<>(Arrays.asList("01", "02", "03"));
src.forEach(item -> {
dest.add("dest: " + item);
});
dest = null;
问题分析
Lambda表达式规则
- 只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。
- 局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
- 不允许声明一个与局部变量同名的参数或者局部变量。
由Lambda表达式规则第二条可知,局部变量dest为隐性final!
总结
Lambda表达式引用的局部变量无论是否声明final,均具有final特性!表达式内仅允许对变量引用(引用内部修改除外,比如list增删),禁止修改!
以下情况均不允许编译通过:
情况一:修改外部局部变量
int n = 0;
src.forEach(item -> {
n = 3;
dest.add("dest: " + item);
});
情况二:Lambda使用外部局部变量,变量隐性final!
int n = 0;
src.forEach(item -> {
dest.add("dest: " + item + n);
});
n = 0;
情况三:声明外部局部变量同名参数
int n = 0;
src.forEach(n -> {
dest.add("dest: " + n);
});