为什么实例字段不需要是最终的或有效的最终的才能在 lambda 表达式中使用?
我正在Java中练习lambda表达式。我知道局部变量需要是最终的或有效的最终的,根据Java SE 16 Lambda Body的Oracle文档:
在 lambda 表达式中使用但未声明的任何局部变量、形式参数或异常参数必须是最终的或实际上是最终的 (§4.12.4),如 §6.5.6.1 中所指定。
它没有说明原因。搜索我发现了类似的问题,为什么lambda中的变量必须是最终的还是有效的最终的?,其中StackOverflow用户“snr”用下一个引号回应:
到目前为止,Java 中的局部变量一直不受争用条件和可见性问题的影响,因为只有执行声明它们的方法的线程才能访问它们。但是,lambda 可以从创建它的线程传递到另一个线程,因此,如果由第二个线程计算的 lambda 能够变异局部变量,则该免疫力将会丧失。
- 来源:为什么限制局部变量捕获?
这就是我的理解:一个方法一次只能由一个线程(假设thread_1)执行。这可确保该特定方法的局部变量仅由thread_1修改。另一方面,lambda可以传递到不同的线程(thread_2),因此...如果thread_1以 lambda 表达式结束并继续执行方法的其余部分,则可以更改局部变量的值,同时,thread_2可能会更改 lambda 表达式中的相同变量。然后,这就是存在此限制的原因(局部变量必须是最终的或有效的最终变量)。
很抱歉冗长的解释。我说得对吗?
但接下来的问题是:
- 为什么这种情况不适用于实例变量?
- 如果thread_1在thread_2的同时更改实例变量(即使它们不执行 lambda 表达式),会发生什么情况?
- 实例变量是否以其他方式受到保护?
我对Java没有太多经验。抱歉,如果我的问题有明显的答案。