在for循环声明中初始化变量的范围实际上不仅仅是块范围吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在for循环声明中初始化变量的范围实际上不仅仅是块范围吗?相关的知识,希望对你有一定的参考价值。
考虑一个带计数器的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
不在此范围内,当它还具有“阻止”范围并且在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-loop声明范围”?如果是这样,我对如何在Java或C#等规范中定义此范围以及程序员通常所称的范围感兴趣。
编辑:是的,我知道我可以将循环声明为for (int j, i = 0; i < 100; i += j)
,但这仍然表明for
循环声明的范围比它们的大括号更高。
JLS 6.3指明范围界定的面部原因:
在for语句(第14.14.1节)的ForInit部分中声明的局部变量的范围包括以下所有内容:
- 它自己的初始化程序
- for语句的ForInit部分右侧的任何其他声明符
- for语句的Expression和ForUpdate部分
- 包含的声明
“包含声明”for
身体。对for
体中定义的变量没有特殊的范围规则。正常规则适用。 (它们也在JLS 6.3中。)
这种语言设计背后的原因包括(我猜1)以下内容:
- 如果你不得不在循环体内查看声明为there2的变量,那么可读性就不好了。
- 确定循环中声明的变量是否已明确初始化的逻辑很难指定,并且程序员很难理解。例:
for (i = 1; i < 10; i = i + j) { int j; if (i > 3) { j = 42; } // do stuff }
1 - 真正的原因只能在20世纪70年代为C的设计师所知。我怀疑Java设计者是否认为它与C不同。他们试图使Java“像C一样”。
2 - 循环体中的某些东西可以修改循环变量是很糟糕的。 :-(
第一个Scope以void main {}开头,而不是像你的for循环范围一样在其他内部块之后,所有用第一个块声明的变量对于所有内部块范围都是可见的,我们必须在使用之前声明变量(在你的情况下)变量j)你在for循环中使用了变量而没有声明它,因此在声明之前不可能使用它并且我们的光标到达for循环由于从上到下逐行逼近它首先声明变量是否声明变量?
一个非常有趣的问题。如果从运行时透视图中查看j,则会提出一个非常好的观点,即在迭代后调用increment表达式时j应该是可见的。
但是从编译器的角度来看,当它读取for循环语句,即(int i = 0; i < 100; i += j)
时,它会期望j已经被声明。
我想你可以说我有一个额外的声明范围,与i和j都有的块范围相比。
变量J在声明/初始化之前被引用。当第一次循环执行时,JVM将没有对它的引用。
您已在循环内初始化变量j。
我希望这能解决你的问题。
以上是关于在for循环声明中初始化变量的范围实际上不仅仅是块范围吗?的主要内容,如果未能解决你的问题,请参考以下文章