考虑一个 for
用计数器循环:
for (int i = 0; i < 100; i++ /* `i` is visible here */) {
/* `i` is visible here */
}
/* `i` not visible here */
一切顺利。 We say that i
has "block" scope.
但是,为什么在for
中声明的变量呢?在 i++
处无法访问循环?
例如,为什么是j
不在此处的范围内,当它也具有“ block ”范围并且在 i += j
之前的时间段内声明时?
for (int i = 0; i < 100; i += j /* only `i` is visible here */) {
int j = 1;
/* `i` and `j` are visible here */
}
/* `i` and `j` are not visible here */
我看到很多关于 i
范围的问题, 但与 j
的范围无关在 for
内循环括号。这是否意味着在技术上还有另一个没有人谈论的范围,即“for 循环声明范围”?如果是这样,我感兴趣的是这个范围在 Java 或 C# 等规范中是如何定义的,以及它通常被程序员称为什么范围。
编辑:是的,我知道我可以将循环声明为 for (int j, i = 0; i < 100; i += j)
,但这仍然表明 for
循环声明的作用域比它们的花括号更大。
最佳答案
面部原因JLS 6.3以这种方式指定范围:
The scope of a local variable declared in the ForInit part of a basic for statement (§14.14.1) includes all of the following:
- Its own initializer
- Any further declarators to the right in the ForInit part of the for statement
- The Expression and ForUpdate parts of the for statement
- The contained Statement
for
主体的“包含语句”。 for
主体中定义的变量没有特殊的范围规则。正常规则适用。 (它们也在 JLS 6.3 中。)
这种语言设计背后的原因包括(我猜想1)以下几点:
- 如果您必须在循环体内查看声明2 的变量,那么可读性会很差。
确定循环中声明的变量是否已明确初始化的逻辑很难指定,程序员也很难理解。示例:
for (i = 1; i < 10; i = i + j) { int j; if (i > 3) { j = 42; } // do stuff }
1 - 真正的原因只有 C 语言的设计者才知道……在 1970 年代。我怀疑 Java 设计者是否考虑过与 C 不同的做法。他们试图让 Java “像 C”。
2 - 循环体中的某些内容可能会修改循环变量,这已经够糟糕了。 :-(
关于java - 在 for 循环声明中初始化的变量的范围实际上不仅仅是 block 范围吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37892846/