Variable used in lambda expression should be final or effectively final
Variable used in lambda expression should be final or effectively final
一、错误原因
使用forEach对list进行循环操作的时候,提示Variable used in lambda expression should be final or effectively final。
中文翻译:lambda表达式中使用的变量应该是final或者有效的final。
具体原因:
1.在 Java 8 之前,匿名类中如果要访问局部变量的话,那个局部变量必须显式的声明为 final。
2.lambda表达式是由匿名内部类演变过来的,他们的作用都是实现接口方法,于是类比匿名内部类,lambda表达式中使用的变量也需要是final类型。
接下来看一个其他的例子
将BorrowerSet赋值到另一个Set中就可以通过编译
那为什么finalBorrowerSet不是声明为final类型的呢?
Java 8 之后,在匿名类或 Lambda 表达式中访问的局部变量,如果不是 final 类型的话,编译器自动加上 final 修饰符。
思考:为什么 lambda 表达式或者匿名内部类不能访问非 final 的局部变量,为什么呢?
这就要说到Jvm内存模型和线程,因为实例变量存在堆中,而局部变量是在栈上分配,lambda 表达(匿名内部类) 会在另一个线程中执行。如果在线程中要直接访问一个局部变量,可能线程执行时该局部变量已经被销毁了,而 final 类型的局部变量在 Lambda 表达式(匿名类) 中其实是局部变量的一个拷贝。
二、正确使用
1.使用final定义局部变量,forEach中局部变量不能自增。(其实这种方法相当于达不到目的,推荐下面第二种)
2.使用AtomicInteger类
有兴趣可以继续学习->点击AtomicInteger详解
使用AtomicInteger类创建出对象,再调用incrementAndGet()方法进行自增。
总结
以上就是今天要分享的内容,如果有什么不懂的地方或者有什么出错的地方,欢迎前来探讨,谢谢大家~
能够帮助你们解决问题是博主的荣幸,你们的支持是我创作的最大动力!:)欢迎关注点赞
更多推荐
所有评论(0)