以下程序没有自己的重要性。它只计算使用类计数器内部的静态字段通过使用for循环创建的对象数量,如下所示。
package temp;
final class Counter
{
private static int cnt;
public Counter()
{
cnt++;
}
public static int show()
{
return(cnt);
}
}
final public class Main
{
public static void main(String[] args)
{
for (int i=0;i<50;i++)
{
Counter counter=new Counter();
}
/*for (int i=0;i<50;i++)
Counter counter=new Counter();*/
System.out.print("\nNumber of objects constructed:->"+Counter.show()+"\n\n");
}
}
这里唯一的问题是注释for循环意味着与上面的for循环相同(同样的东西也应用于while循环)根本不起作用导致编译时错误,表明“< em> not a statement “意味着在这种特殊情况下,即使for循环只包含一个语句,这对括号也是必需的!为什么呢?
答案 0 :(得分:27)
要了解发生这种情况的原因,您必须在语言规范中查看Java's Blocks and Statements syntax。
ForStatement定义为:
ForStatement:
for ( ForInitopt ; Expressionopt ; ForUpdateopt )
Statement
声明定义为:
Statement:
StatementWithoutTrailingSubstatement
LabeledStatement
IfThenStatement
IfThenElseStatement
WhileStatement
ForStatement
StatementWithoutTrailingSubstatement:
Block
EmptyStatement
ExpressionStatement
SwitchStatement
DoStatement
BreakStatement
ContinueStatement
ReturnStatement
SynchronizedStatement
ThrowStatement
TryStatement
然后,看看Block:
Block:
{ BlockStatementsopt }
BlockStatements:
BlockStatement
BlockStatements BlockStatement
BlockStatement:
LocalVariableDeclarationStatement
ClassDeclaration
Statement
您会注意到,在此规范中,LocalVariableDeclarationStatement无效,除非它在块中。但是,因为ForStatement要求它后跟一个语句,所以必须存在括号以使表达式有效。因此,任何局部变量声明在没有括号的循环中都是无效的。
答案 1 :(得分:6)
因为您正在创建范围变量。 Java告诉你这没有任何作用,因为它所做的就是分配内存,一旦循环再次通过,你就会失去那个并创建一个新的。基本上整个循环都是一个NOP,这就是为什么它告诉你它减少为无所作为的声明。
循环是NOP我的意思是循环中的声明是NOP。
带括号的版本工作的原因是编译器不检查范围内的用法,因为有大括号。这可能与从一行语句生成的解析树与存在完整循环范围时创建的解析树有关。
答案 2 :(得分:4)
@JasCav是对的,但你可以编译它:
for (int i=0;i<50;i++)
new Counter();
答案 3 :(得分:4)
你也可以通过这种方式让它无需支撑:
Counter counter;
for (int i = 0; i < 50; i++)
counter = new Counter();
并不是说你有任何理由想做这样的事情。 离开括号是一个真的坏主意,因为添加一个语句实际上会使控制流发生变化。