当前位置: 首页 > 知识库问答 >
问题:

Java 8 Lambda 变量作用域 [重复]

夔波
2023-03-14

我有 2 个代码示例:

int[] idx = { 0 };
List<String> list = new ArrayList<String>();
list.add("abc");
list.add("def");
list.add("ghi");
list.stream().forEach(item -> {
    System.out.println(idx[0] + ": " + item);
    idx[0]++;
});

工作正常。

虽然这段代码有编译错误:

int idx = 0;
List<String> list = new ArrayList<String>();
list.add("abc");
list.add("def");
list.add("ghi");
list.stream().forEach(item -> {
    System.out.println(idx + ": " + item);
    idx++;
});

说:

Local variable idx defined in an enclosing scope must be final or effectively final.

唯一的区别是idxint或int数组。

根本原因是什么?

共有3个答案

邓鸿雪
2023-03-14

一个变量或参数的值在初始化后从未改变,它实际上是最终的。

在案例1中:

< code>int[] idx不变,如果你替换< code > idx[0];到< code > idx = { 1 };将编译错误

在情况2中:

如果您删除 idx ;它将编译良好

汪坚
2023-03-14

我对你的观察有部分解释。Java 8 代码中初始化的数组被视为有效的最终数组,因为它的值在初始化后不会更改。这就是为什么 int[] idx = { 0 }; 代码版本正在通过的原因。所以我希望如果你让int idx有效地最终,那么它也会通过。一种方法是通过声明它来正式使这个变量成为最终变量,即最终的int idx = 0

丘向荣
2023-03-14

根本原因是JVM缺乏构造局部变量引用的机制,当idxint或某些不可变类型(例如String)时,执行idx需要这种机制。由于您尝试改变idx,因此仅捕获其值是不够的;Java需要捕获引用,然后通过它修改值。

当您使用数组时,Java没有这个问题,因为数组是引用对象。Java可以捕获从不更改的数组引用,并使用该不更改的引用来改变对象。数组本身提供了必要的间接级别,因为Java数组是可变的。

我尝试使<code>idx

因为在这种情况下,lambda不需要捕获对原始类型的局部变量的引用。对静态变量的引用很容易获得,所以捕获它没有问题。

同样,如果您将 idx 设置为成员变量,并在实例方法中使用 lambda,则该代码将起作用。这将允许 lambda 通过对象修改 idx 字段,该对象可以自由捕获。

 类似资料:
  • 变量作用域 变量的作用域值的是变量的生命周期和作用范围(全局与局部作用域的区别)。 作用域介绍 静态作用域 静态作用域有称为词法作用域,即指其在编译的阶段就可以决定变量的引用。静态作用域只更变量定义的位置有关与代码执行的顺序无关。 var x = 0; function foo() { alert(x); } function bar() { var x = 20; foo(); }

  • 任何编程中的范围都是程序的一个区域,其中定义的变量可以存在,并且超出该变量无法访问。 有三个地方,其中变量可以用Pascal编程语言声明 - 在子程序或块中,称为局部变量 在所有子程序之外,称为全局变量 在子程序参数的定义中称为形式参数 让我们解释什么是local和global变量和形式参数。 局部变量 (Local Variables) 在子程序或块内声明的变量称为局部变量。 它们只能由子程序或

  • 如果你之前用过像Python或者Ruby之类的动态语言,现在你可能已经熟悉了Vim脚本的变量。你会发现Vim变量的大部分内容跟你想的一样,不过有一个东西可能会不同,那就是变量的作用域。 在两个分隔的窗口中分别打开两个不同的文件,然后在其中一个窗口中执行下面的命令: :::vim :let b:hello = "world" :echo b:hello 如你所愿,Vim会显示world。现在切换到

  • 范围是程序的一个区域,从广义上讲,有三个地方,可以声明变量 - 在函数或块中称为局部变量, 在函数参数的定义中称为形式参数。 在所有函数之外,称为全局变量。 我们将在后续章节中学习什么是函数及其参数。 这里让我们解释什么是局部变量和全局变量。 局部变量 (Local Variables) 在函数或块内声明的变量是局部变量。 它们只能由该函数或代码块中的语句使用。 本地变量不为其自身以外的函数所知。

  • 作用域是程序的一个区域,一般来说有三个地方可以定义变量: 在函数或一个代码块内部声明的变量,称为局部变量。 在函数参数的定义中声明的变量,称为形式参数。 在所有函数外部声明的变量,称为全局变量。 我们将在后续的章节中学习什么是函数和参数。本章我们先来讲解什么是局部变量和全局变量。 局部变量 在函数或一个代码块内部声明的变量,称为局部变量。它们只能被函数内部或者代码块内部的语句使用。下面的实例使用了

  • 我在研究JS中变量作用域的概念时,在上面发现了这个例子: 此函数的输出为 现在我很困惑,为什么gets会在第二个日志中获得值3。即使在语句中使用声明时也是如此。在中声明的不是应该在中获得一个新实例吗?