Java Lambda的变量捕获
来源:互联网 发布:unity网络游戏源码 编辑:程序博客网 时间:2024/06/14 22:40
如果曾经使用过C++的Lambda表达式,那么就会知道C++有一个变量捕获列表
有两种捕获方式,一种是引用捕获,一种是变量捕获。与C++函数的传引用、传值相对应。
而Java与C++不同 ,java只有引用捕获
例如:
ScheduledExecutorService ses = Executors.newScheduledThreadPool(5);
int a=0;
for(inti=1;i<=10;i++){
ses.schedule(()->{
System.out.println(a);
},i,TimeUnit.MILLISECONDS);
}
通过编译
ScheduledExecutorService ses = Executors.newScheduledThreadPool(5);
int a=0;
for(inti=1;i<=10;i++){
ses.schedule(()->{
System.out.println(a);
},i,TimeUnit.MILLISECONDS);
}
a=1;
编译失败
那么此时我们可以输出i吗? 答案是不可以的
因为i并不final
那么如何才能输出变量i
i作为field是否可以呢?
private int i = 0;
public void run(){
ScheduledExecutorService ses = Executors.newScheduledThreadPool(5);
for(i=1;i<=10;i++){
ses.schedule(()->{
System.out.println(i);
},i,TimeUnit.MILLISECONDS);
}
}
编译通过,结果不正确
输出10个 “11”
这是因为执行计划任务的时候 i已经变了。这也说明java不是值捕获。
此时可以创建final的变量作为跳板,帮助我们实现此功能
ScheduledExecutorService ses = Executors.newScheduledThreadPool(5);
for(inti=1;i<=10;i++){
final int curi=i;
ses.schedule(()->{
System.out.println(curi);
},i,TimeUnit.MILLISECONDS);
}
为什么这样声明就可以了呢?
在创建lambda表达式的时候,lambda用到的外部引用都被复制了一份(因为局部变量在栈内存中,稍后会被销毁)。
这样看来java的lambda在需要捕获基础类型值的场景下,不如C++灵活
而final的限制,可以减少人为的错误
- Java Lambda的变量捕获
- Java 8 Lambda 捕获外部变量 -- 不可变的原因
- c++ lambda 捕获成员变量
- C++11 Lambda的变量捕获和Lambda在Qt中的应用
- C++11 Lambda的变量捕获和Lambda在Qt中的应用
- c++ lambda表达式捕获变量参数
- Java Lambda(语言篇——lambda,方法引用,目标类型,默认方法,函数接口,变量捕获)
- [C# 5.0 IN A NUTSHELL,5th Edition读书笔记]Lambda表达式捕获(capture)迭代中的变量的相关问题
- c++ lambda捕获列表
- JAVA lambda的使用
- C++14 泛型lambda(支持显式的lambda捕获列表)
- Capturing versus non-capturing lambdas 捕获和非捕获的Lambda表达式
- Java 8 里的 Lambda
- java lambda内容的介绍
- Java lambda内容的介绍
- Java lambda表达式的应用
- JAVA lambda表达式的实例
- Java lambda 表达式的基础知识
- MySQL系列—全文检索(fulltext)使用
- 罚抄
- 更新数据库里table,参数要搞清楚,传正确
- Vue2.0 探索之路——生命周期和钩子函数的一些理解
- git 基础入门使用
- Java Lambda的变量捕获
- iOS11 适配
- 名词解释之缓存
- 微信小程序之语言开发
- make Project、clean Project、Rebuild Project的区别
- nyoj17 单调递增最长子序列
- 实现循环音视频转换
- 使用swt时遇到的eclipse与工程版本不兼容问题
- Linux系统下/tmp目录下的临时文件清理