前几天我在与Java同事讨论这段代码:
for( ; ; ) { }
这里没什么特别的,只是一个无限循环。
但我们想知道为什么这在语法上是正确的。如果您查看JLS §14.14.1,您会看到:
for ( [ForInit] ; [Expression] ; [ForUpdate] ) Statement
我了解ForInit
和ForUpdate
可以省略。但至少我希望Expression
是强制性的,就像在while循环中一样:
while() {} // compile error, Expression is missed
那么为什么可以在for循环中省略Expression?甚至一个人想得更多 - 为什么错过表达式解析为true
?我的期望是将空表达式解析为false
。
同样的想法对其他语言也有效(我用C和JavaScript尝试它,但我相信所有带有for循环的语言都以这种方式运行)。
为什么表达式子句在for循环中不是必需的(但是在while循环中)?为什么空表达式解析为true
而不是false
?
答案 0 :(得分:3)
理由开始in JLS 14.14.1.1并继续进入14.14.1.2,强调我的。
如果
ForInit
部分不存在,则不会采取任何措施。如果
Expression
不存在,或者它存在并且其评估产生的值(包括任何可能的拆箱)为真,则包含的Statement
为执行...
JLS允许空白的ForInit
,Expression
和ForUpdate
声明并且有条件来处理它们的缺席,因此可以省略它们。
使用while
循环,per JLS 14.12, 是允许的。
Expression
必须包含boolean
或Boolean
类型,否则会发生编译时错误。
由此,规范不允许传递空白表达式,因为这会导致每个上面的编译时错误。
如果您正在寻找更具历史意义的原因,请C specification mandates this as well。
由于Java从C中获得了很多灵感(并且大部分都在其中实现),因此Java的循环行为与C&C的循环类似,这是完全合理的,这就是它们的行为方式:表达式是在C' for
语句中是可选的,在while
语句中是强制性的。