Variable used in lambda expression should be final or effectively final

当在lambda表达式中试图修改局部变量时,编译器会报错:

Variable used in lambda expression should be final or effectively final.

解决办法:用final修饰修饰局部变量,如果表达式中非要对局部变量做修改,可以对变量做封装。当然,如果是基本数据类型,可以使用对应的原子类型。

问题得以解决,但是有个疑问:为什么需要对局部变量做final修饰,或者让局部变量成为有效的最终变量(effectively final)?

网上找了很多资料,许多人都说是为了解决线程安全问题,其中有些资料说lambda 表达(匿名内部类) 会在另一个线程中执行。这种说法是可以推翻的,有兴趣的朋友可以在表达式中打印线程相关信息,与外部方法的线程信息做比较。

要搞明白这个问题,需要了解“闭包”一词,可自行百度。

在java中是存在闭包的,只是匿名内部类对闭包做的不够好。在匿名内部类中,会拷贝一份局部变量的副本(反编译后可见),这样一来,当修改了局部变量的信息,比如让局部变量的引用指向一个新的内存地址,局部变量与匿名内部类中的副本无法同步。因此需要对局部变量做final修饰。对实例变量和静态变量来说,是不存在这种问题的,因为匿名内部类中有对外部类的引用,访问实例变量时只需要this.变量即可。

lambda表达式同理,只不过java 8考虑到对于所有的这种问题,编程人员都需要用final修饰局部变量。因此为了方便,定义局部变量的时候,不需要显示地添加final修饰符。

上述只是个人理解,望批评指正。

email:18642984053@163.com

以下文章可供参考:

https://www.cnblogs.com/devilwind/p/8635946.html

https://www.zhihu.com/question/24084277/answer/110176733

https://blog.csdn.net/hzy38324/article/details/77986095

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值