为什么增强型 for 循环的局部变量必须是局部变量?
根据 Java 语言规范 § 14.14.2,增强型循环的变量必须是循环的局部变量。换句话说,这将编译:for
for (State state : State.values()) {
// do something for each state
}
但这不会:
State state;
for (state: State.values()) {
// do something for each state
}
JLS没有给出这种语言设计选择的理由。我可以理解为什么如果局部变量由注释修改或由注释修改,为什么类型名称必须存在,但我不明白为什么不允许在其他地方声明的变量的裸名称。有没有人对为什么施加这种限制有任何见解?final
编辑
到目前为止,有几个答案似乎表明,在循环之外发生的事情是以这种方式设计语言的原因。也许仔细研究JLS所说的内容会澄清为什么我觉得这没有说服力。考虑这个循环,其中是枚举:State
for (State state : State.values()) {
// ...
}
State.values()
是一个数组,因此根据 JLS,该循环在功能上与以下相同:
State[] a = State.values();
for (int i = 0; i < a.length; i++) {
State state = a[i];
// ...
}
现在很明显,后一个循环可以写成:
State state;
State[] a = State.values();
for (int i = 0; i < a.length; i++) {
state = a[i];
// ...
}
从概念上讲,最后一个(完全合法的)循环可以用作上面第二个增强循环(不编译的循环)的功能等效物。for
类似地,如果 是一个(不是数组),则此循环:stateList
Iterable<State>
for (State state : stateList) {
// ...
}
在功能上与以下各项相同:
for (Iterator<State> iterator = stateList.iterator(); iterator.hasNext(); ) {
State state = iterator.next();
// ...
}
像以前一样,后一个循环可以这样写:
State state;
for (Iterator<State> iterator = stateList.iterator(); iterator.hasNext(); ) {
state = iterator.next();
// ...
}
同样,这可以用作(非法)的功能等价物:
State state;
for (state : stateList) {
// ...
}
在每种情况下,当循环退出时,的值是完全定义的(如果,也许,无用)。此外,就像常规循环一样,可以在编译时捕获使用未定义的裸变量名称(例如,行丢失或超出范围)的增强循环。那么从语言设计的角度来看,问题出在哪里呢?为什么语言设计者取缔了这个结构?state
for
State state;