java - 为什么 lambda 中使用的局部变量必须是最终的或实际上是最终的?

标签 java java-8

这个问题在这里已经有了答案:

但是我读了一篇文章(Why Do Local Variables Used in Lambdas Have to Be Final or Effectively Final?)。它发布了一个示例:

Supplier<Integer> incrementer(int start) {
  return () -> start++;
}

代码会产生编译错误。该帖子试图解释原因并说:

The basic reason this won't compile is that the lambda is capturing the value of start, meaning making a copy of it. Forcing the variable to be final avoids giving the impression that incrementing start inside the lambda could actually modify the start method parameter. But, why does it make a copy? Well, notice that we are returning the lambda from our method. Thus, the lambda won't get run until after the start method parameter gets garbage collected. Java has to make a copy of start in order for this lambda to live outside of this method.

我看不懂它的解释,有两个问题:

  1. “在 start 方法参数被垃圾回收之前,lambda 不会运行”是什么意思?
  2. 为什么要复制?

最佳答案

  1. 这意味着 lambda 代码(start++ 部分)直到 Supplier 才会执行。对象的 get() 方法被调用,这发生在 incrementer() 方法的调用者的某处,即 之后的某个时间incrementer() 方法已返回。

    谁写的就大错特错了,因为参数在栈上,而不是堆上,所以它们不会被“垃圾收集”。鉴于这样一个巨大的错误,我建议你忽略那个帖子,因为作者不知道他在说什么。

  2. 这已经在 accepted answer 中涵盖了您提供的第一个链接。我建议你阅读它。

关于java - 为什么 lambda 中使用的局部变量必须是最终的或实际上是最终的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58527869/

相关文章:

java - (Mac)jshell找不到运行环境

JavaFx 相当于 Swing JFrame

java - 如何将 WebRTC 视频流视为虚拟网络摄像头

java - JFrame 非常小,使用空布局

java - 使用 lambda 将文本文件转换为 Map<String, List<String>>

java - 支持 Java 8 的反编译器?

java - 泛型类型推断不适用于方法链接?

java - 如果数组中存在一组特定的数字,我该如何计数

C#/Java/Ruby - 密码哈希算法 - 跨语言/平台

java - 使用一系列 lambda 函数来定义类功能是否合适?