Lambda关于外部变量的引用(Variable used in lambda expression should be final or effectively final)

1、背景

在匿名函数中修改外部变量,出现这个提示
Lambda关于外部变量的引用(Variable used in lambda expression should be final or effectively final)_第1张图片

2、原因

需要了解

AtomicBoolean(AtomicInt等也是一样):
AtomicBoolean 可用在应用程序中(如以原子方式更新的标志),但不能用于替换 Boolean。

换一句话说,Atomic就是原子性的意思,即能够保证在高并发的情况下只有一个线程能够访问这个属性值。(类似我们之前所说的volatile)

一般情况下,我们使用 AtomicBoolean 高效并发处理 “只初始化一次” 的功能要求

正文

在java编译时,匿名内部类也会被当作普通的类处理,只不过编译器生成它构造方法的时候,除了将外部类的引用传递了过来,还将基本数据类型的变量复制了一份过来,并把引用数据类型的变量引用也传递了过来。因此,基本数据类型的变量当然不能修改了,不然就会跟外部的变量产生不一致,这样的话变量的传递也就变得毫无意义了。

也就是说,java之所以这么做,是为了保证数据的一致性

重点: 基本数据类型是复制了值的,引用数据类型是复制了地址的

因此,在匿名函数中,如果不使用原子型的基本数据类型的话,是不能修改的,而引用数据类型的话就可以通过使用set方法修改值,但是不能new一个对象赋予引用数据类型(值传递的内容,具体可以百度)。
Lambda关于外部变量的引用(Variable used in lambda expression should be final or effectively final)_第2张图片

Lambda关于外部变量的引用(Variable used in lambda expression should be final or effectively final)_第3张图片

注意: Java 8 之后,在匿名类或 Lambda 表达式中访问的局部变量,如果不是 final 类型的话,编译器自动加上 final 修饰符,即 Java8 新特性:effectively final。

你可能感兴趣的:(java,jvm,开发语言)