这是我的代码:
class HelloWorld {
char[] foo = {'a', 'b'};
// This will compile
void foo() {
for (char foo : foo) {
}
}
// This will not compile
void bar() {
for (char foo = 0; foo < foo.length; foo++) {
}
}
}
foo
如何编译,但编译bar
失败的原因为:
Error: char cannot be dereferenced
在foo编译中生成循环但是bar失败的两个循环声明之间有什么区别?
答案 0 :(得分:15)
我们可以通过查看JLS§14.14.2关于处理数组时增强型for
如何工作的描述来看到差异:
增强的for语句相当于表单的基本for语句:
T[] #a = Expression; L1: L2: ... Lm: for (int #i = 0; #i < #a.length; #i++) { {VariableModifier} TargetType Identifier = #a[#i]; Statement }
注意变量是如何在循环的 body 中声明的,而不是循环的标题。也就是说,您的foo
函数是这样的:
void foo() {
{ // Freestanding block for scope, though not really needed as `foo` has
// nothing else in it
char[] a = foo; // T[] #a = Expression;
for (int i = 0; i < a.length; i++) {
char foo = a[i]; // {VariableModifier} TargetType Identifier = #a[#i];
}
}
}
这就是为什么你在增强的for
中躲避阴影,而不是传统的for
,它需要访问原始数组(以获取其length
) i
的条目等。)
有关How does the Java 'for each' loop work?中增强的for
循环及其答案的详情。
答案 1 :(得分:8)
Java语言规范以两种不同的方式定义两个char foo
的范围:
在基本的 ForInit 部分中声明的局部变量的范围
for
声明(第14.14.1节)包括以下所有内容:
- 自己的初始化程序
for
声明的 ForInit 部分右侧的任何其他声明符for
声明的表达式和 ForUpdate 部分- 包含的声明
在 FormalParameter 部分中声明的局部变量的范围 增强的
for
语句(第14.14.2节)是包含的语句。
这完美地解释了您观察到的行为:本地foo
在基本for
循环的控制子句中的范围内(声明右侧的任何地方),因此它会影响另一个foo
1}}但是在增强的for
循环中,它的作用域只是循环语句 - 它不在循环控制子句中的任何位置。