private void m10(String[] arr) {
for (String s : arr) {
Supplier<String> supplier = () -> {
System.out.println(s);
return null;
};
supplier.get();
}
}
Run Code Online (Sandbox Code Playgroud)
要么
private void m10(Object[] arr) {
for (Object s : arr) {
Supplier<String> supplier = () -> {
System.out.println(s);
return null;
};
supplier.get();
}
}
Run Code Online (Sandbox Code Playgroud)
private void m11(String[] arr) {
for (int i = 0; i < arr.length; i++) {
Supplier<String> supplier = () -> {
System.out.println(arr[i]);
return null;
};
supplier.get();
}
}
Run Code Online (Sandbox Code Playgroud)
在情况2中,我知道该变量i实际上不是最终变量,因为其值在循环迭代之间发生了变化。但是我不明白为什么lambda可以在情况1下工作。
s永不更改(s = ...)。因此,编译器说“是的,理论上我们可以将其标记为final”。那就是有效的final的意思。也就是说,您没有标记它,final但是您可以并且它仍然可以编译。
如果您想了解增强的for循环:
for (String s : arr)
Run Code Online (Sandbox Code Playgroud)
该变量不会超出的范围,for并且不会得到重新分配。即不是:
String s = null;
for (int i = 0; i < arr.length; i++) {
s = arr[i];
...
}
Run Code Online (Sandbox Code Playgroud)
该变量是在循环内部创建的,因此其范围仅限于循环。它不会重复使用,而是在每次迭代时都丢弃并重新创建:
for (int i = 0; i < arr.length; i++) {
String s = arr[i];
...
}
Run Code Online (Sandbox Code Playgroud)
仔细看两个例子。首先,您无法编写代码final String s = null;,因为我们正在循环中重新分配它s = arr[i];。但是在第二个示例中我们可以,因为该变量s仅在一次迭代中已知,然后又被丢弃。所以final String s = arr[i];是好的。
作为附带说明,这也解释了为什么s循环后无法使用。它是未知的且已被破坏,其范围仅限于循环。