一、错误原因

使用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()方法进行自增。

在这里插入图片描述


总结

以上就是今天要分享的内容,如果有什么不懂的地方或者有什么出错的地方,欢迎前来探讨,谢谢大家~

能够帮助你们解决问题是博主的荣幸,你们的支持是我创作的最大动力!:)欢迎关注点赞

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐