Java 数组作为局部变量-不遵循Lambda中的确定赋值规则
您已经看到了以下线程: 据 使用的任何局部变量、形式参数或异常参数 在lambda表达式中未声明的必须声明为final或final 实际上是最终的(§4.12.4),否则在以下情况下会发生编译时错误: 已尝试使用 在lambda主体中使用但未声明的任何局部变量必须 在lambda之前明确分配(§16(明确分配)) 或发生编译时错误 关于变量使用的类似规则适用于内部类的主体 (§8.1.3). 对有效最终变量的限制禁止 访问动态更改的局部变量,其捕获将 可能会引入并发问题。与决赛相比 限制,它减少了程序员的文书负担Java 数组作为局部变量-不遵循Lambda中的确定赋值规则,java,lambda,java-8,Java,Lambda,Java 8,您已经看到了以下线程: 据 使用的任何局部变量、形式参数或异常参数 在lambda表达式中未声明的必须声明为final或final 实际上是最终的(§4.12.4),否则在以下情况下会发生编译时错误: 已尝试使用 在lambda主体中使用但未声明的任何局部变量必须 在lambda之前明确分配(§16(明确分配)) 或发生编译时错误 关于变量使用的类似规则适用于内部类的主体 (§8.1.3). 对有效最终变量的限制禁止 访问动态更改的局部变量,其捕获将 可能会引入并发问题。与决赛相比 限制,它
数组
是规则的例外吗
验证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
是int
类型的变量,这里v
的值是2,它是final
变量。当您尝试分配5时,它给出了错误,因为您无法更改变量值(按预期工作)
在第二种情况下,
v
不是int
类型的变量,它是一个数组。在Java中,数组是对象,因此这里v
是一个引用。通常,引用引用一个对象并包含该对象的地址。当您尝试在此处执行v[0]=5
时,您需要更改对象内部的值,但不更改引用的值。如果您尝试执行v=newint[1]
或v={5}
,那么您将得到编译错误在第一种情况下v
是int
类型的变量,这里v
的值是2,它是最终的变量。当您尝试分配5时,它给出了错误,因为您无法更改变量值(按预期工作)
在第二种情况下,v
不是int
类型的变量,它是一个数组。在Java中,数组是对象,因此这里v
是一个引用。通常,引用引用一个对象并包含该对象的地址。当您尝试在此处执行v[0]=5
时,您需要更改对象内部的值,但不更改引用的值。如果您尝试执行v=new int[1]
或v={5}
,那么您将得到编译错误您没有分配给v
,因此,您没有违反最终分配规则。分配给v[0]
是一件完全不同的事情。与final Point p=new Point()没有什么不同代码>,然后分配p.x=4
和访问lambda表达式中的p.x
。@CommonMan-投票结束,因为此问题是由无法再复制的问题或简单的印刷错误引起的。虽然类似的问题可能在这里的主题,这是一个解决的方式不太可能帮助未来的读者。这通常可以通过在发布前确定并仔细检查重现问题所需的最短程序来避免。您需要执行v=someotherarray
,以违反最终分配。更新v[0]
不会更新对象本身的任何分配。@Holger,我明白你的意思了+1@nullpointer,我想它可能会帮助一些人,所以我把它放在这里,我得到了这个概念,兄弟,想节省人们在将来偶然发现这个的时间。你没有分配给v
,因此,你没有违反最终分配规则。分配给v[0]
是一件完全不同的事情。与final Point p=new Point()没有什么不同代码>,然后分配p.x=4
和访问lambda表达式中的p.x
。@CommonMan-投票结束,因为此问题是由无法再复制的问题或简单的印刷错误引起的。虽然类似的问题可能在这里的主题,这是一个解决的方式不太可能帮助未来的读者。这通常可以通过在发布前确定并仔细检查重现问题所需的最短程序来避免。您需要执行v=someotherarray
,以违反最终分配。更新v[0]
不会更新对象本身的任何分配。@Holger,我明白你的意思了+1@nullpointer,我想它可能会帮助一些人,所以我把它放在这里,我得到了这个概念,兄弟,想节省人们以后偶然发现这个的时间。是的,@Sat我理解你的意思,开始时有点困惑,所以我想把它放在这里,可能将来有人会偶然发现这个,并从中受益。是的,@Sat我明白你的意思,一开始有点困惑,所以我想把它放在这里,也许将来有人会偶然发现,并从中受益。
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