一、错误原因
使用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()方法进行自增。
总结
以上就是今天要分享的内容,如果有什么不懂的地方或者有什么出错的地方,欢迎前来探讨,谢谢大家~
能够帮助你们解决问题是博主的荣幸,你们的支持是我创作的最大动力!:)欢迎关注点赞