cod*_*erz 6 java lambda java-8
我有2个代码示例:
int[] idx = { 0 };
List<String> list = new ArrayList<String>();
list.add("abc");
list.add("def");
list.add("ghi");
list.stream().forEach(item -> {
System.out.println(idx[0] + ": " + item);
idx[0]++;
});
Run Code Online (Sandbox Code Playgroud)
好好工作.
虽然此代码有编译错误:
int idx = 0;
List<String> list = new ArrayList<String>();
list.add("abc");
list.add("def");
list.add("ghi");
list.stream().forEach(item -> {
System.out.println(idx + ": " + item);
idx++;
});
Run Code Online (Sandbox Code Playgroud)
他说:
Local variable idx defined in an enclosing scope must be final or effectively final.
Run Code Online (Sandbox Code Playgroud)
唯一的区别是idxint或int数组.
根本原因是什么?
根本原因是JVM缺少构造对局部变量的引用的机制,这是idx++在idx一个int或一些不可变类型(例如String)时需要执行的操作.既然你试图改变idx,只是捕捉它的价值是不够的; Java需要捕获引用,然后通过它修改值.
使用数组时Java没有此问题,因为数组是引用对象.Java可以捕获永不改变的数组引用,并使用该不变的引用来改变对象.数组本身提供了必要的间接级别,因为Java数组是可变的.
我试过make
idxstatic并将它移到main方法之外,工作正常.但为什么?
因为在这种情况下,lambda不需要捕获对基本类型的局部变量的引用.对静态变量的引用很容易获得,因此捕获它没有问题.
类似地,如果您创建idx成员变量,代码将起作用,并在实例方法中使用lambda.这将使lambda idx通过this对象修改字段,可以自由捕获.
| 归档时间: |
|
| 查看次数: |
6725 次 |
| 最近记录: |