考虑一下以下代码片段,在进行重构后,我检查了为什么构建服务器报告了一个损坏的构建,但在我的IDE中还不错:
List<String> text; ... for (String text : text) {...}
因此,对于for-each中的String和List使用相同的名称。
这当然不是很明智,但是在重命名之前遵循了我的烦恼之后,我发现上面的代码可以用JDK 8很好地编译,但是使用JDK 7可以给出以下错误:
error: for-each not applicable to expression type for (String text : text) { ^ required: array or java.lang.Iterable found: String 1 error
我知道在JDK中对该区域的几个部分进行了更改-但是有人能启发我为什么会发生这种行为吗?
更新: 由于我收到了有关不同行为的一些评论,因此这里有一个完整的示例类:
import java.util.Arrays; import java.util.List; public class Strange { List<String> text = Arrays.asList("Max", "Alex", "Maria"); public static void main(String[] args) { new Strange().doSomething("Alex"); } public void doSomething(String name) { for (String text : text) { System.out.println(text.equals("Alex")); } } }
这是编译过程和输出(Windows 7 64bit):
C:\copy>c:\Projects\java\jdk1.7.0_79\bin\javac.exe Strange.java Strange.java:13: error: for-each not applicable to expression type for (String text : text) { ^ required: array or java.lang.Iterable found: String 1 error C:\copy>c:\Projects\java\jdk1.8.0_60\bin\javac.exe Strange.java C:\copy>
结论: 我很困惑,为什么我的IDE(使用8)没有在一个语句中抱怨两次相同的名称- 但是现在很明显,它不是一个语句。我真的想知道,如果JLS另有说明,为什么这一点早已存在。但是无论如何,感谢我收到的见解和出色的回答(这使我很难选择最好的答案)。
虽然推理(使用从增强for循环到传统for循环的指定转换,并由其他答案使用)是正确的,但是有一个关于范围的明确说明:
for
§6.3。声明范围 … 在增强型语句(第14.24.2节)的 FormalParameter 部分中声明的局部变量的范围是所包含的 Statement 。for __
§6.3。声明范围
…
在增强型语句(第14.24.2节)的 FormalParameter 部分中声明的局部变量的范围是所包含的 Statement 。for __
(直接链接)
因此,变量的范围不包括增强循环的 表达式for …
您可以验证与Java 7 和Java 6相比,这没有改变,尽管两者(我尝试过Java 6 javac)都表现出相互矛盾的行为。
javac
因此,编译器行为的这一变化是一个旧错误的修复……