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

作为局部变量的数组-在Lambda中不遵循明确的赋值规则

太叔睿
2023-03-14

看到了以下线程:

Java8流编译器消息——局部变量必须是final或实际上是final

lambda表达式中的变量赋值

根据JavaDoc

在lambda表达式中使用但未声明的任何局部变量、形式参数或异常参数必须声明为final或有效final(§4.12.4),否则在尝试使用时会出现编译时错误。

在lambda主体中使用但未声明的任何局部变量必须在lambda主体之前明确赋值(§16(明确赋值)),否则会发生编译时错误。

关于变量使用的类似规则适用于内部类的主体(§8.1.3)。对有效最终变量的限制禁止访问动态变化的局部变量,这些变量的捕获可能会带来并发问题。与最终限制相比,它减轻了程序员的文书负担。

< code >数组是规则1的例外吗?

验证javadoc的示例程序:

List<Integer> li = Arrays.asList(1,2,3,45,678); 
final int v = 2;
li.stream().filter(e-> e!=v).map(e->e).forEach(System.out::println);
v= 5;   

第v=5行的编译错误;,很明显

违反最终分配规则的示例代码段:

List<Integer> li = Arrays.asList(1,2,3,45,678); 
final int[] v = {2};
li.stream().filter(e-> e!=v[0]).map(e->e).forEach(System.out::println);
v[0]= 5;

输出:

3

45

678

上面的代码片段没有给出编译错误,我遗漏了什么吗??

共有1个答案

燕禄
2023-03-14

在第一种情况下,< code>v是类型为< code>int的变量,这里< code>v的值是2,它是< code>final变量。当你试图赋值5时,它给出错误,因为你不能改变< code>final变量值(按预期工作)。

第二种情况是,< code>v不是< code>int类型的变量,而是一个< code >数组。在Java中数组是对象,所以这里< code>v是一个引用。通常,引用是指一个对象,并包含该对象的地址。当你试图在这里做v[0] = 5时,你改变的是对象内部的值,而不是引用的值。如果您尝试执行< code>v = new int[1]或< code>v={5},则会出现编译错误

 类似资料:
  • 我尝试用forEach循环遍历一个包含三个变量的数组,并将每个变量的值更改为0-255之间的随机数。 我首先给每个变量一个简单的值:

  • 在for循环中为字符串定义值时遇到问题,但我需要它保持不变,即使在循环完成后也是如此。这是我的密码: 我知道如果我给soporte在for或if中赋一个值,它会改变,但我不知道如何做,因为它只是第一次问。还有,代码真的很长。这只是一个片段,所以有些东西是不完整的。P. D.apellido_1是用户的输入,但我使用了将要运行的示例。

  • 我有以下一段代码在我的程序,我正在运行SonarQube 5的代码质量检查后,它与Maven集成。 然而,Sonar要求删除这个对局部变量“session”的无用赋值。

  • 上面所有的变量都有标题中的警告。你能告诉我为什么会这样吗?

  • 局部变量使用关键字 def 来声明,其只在声明它的地方可见 . 局部变量是 Groovy 语言的一个基本特性. 例子 13.2 . 使用局部变量 def dest = "dest" task copy(type: Copy) { form "source" into dest }