Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的对象创建语句不';不允许使用单线环路。为什么?_Java - Fatal编程技术网

Java中的对象创建语句不';不允许使用单线环路。为什么?

Java中的对象创建语句不';不允许使用单线环路。为什么?,java,Java,以下程序本身并不重要。它只是使用类计数器内的静态字段计算通过使用for循环创建的对象数,如下所示 package temp; final class Counter { private static int cnt; public Counter() { cnt++; } public static int show() { return(cnt); } } final public class Ma

以下程序本身并不重要。它只是使用类计数器内的静态字段计算通过使用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");
    }
}
封装温度;
期末班计数器
{
私有静态int-cnt;
公众柜位()
{
cnt++;
}
公共静态int show()
{
返回(cnt);
}
}
最终公开课主
{
公共静态void main(字符串[]args)
{

对于(int i=0;i,因为您正在创建一个作用域变量。Java告诉您这不起任何作用,因为它所做的只是分配内存,一旦循环再次通过,您就会丢失该循环并创建一个新的循环。本质上,整个循环是一个NOP,这就是为什么它告诉您它减少为一个do nothing语句的原因

循环是NOP,我的意思是循环中的声明是NOP


带大括号的版本之所以有效,是因为编译器没有检查作用域内的用法,因为存在大括号。这可能与由单行语句生成的解析树与存在完整循环作用域时创建的解析树有关。

@JasCav是对的,但是您可以让它编译:

for (int i=0;i<50;i++)
    new Counter();

for(inti=0;i要理解为什么会发生这种情况,您必须查看语言规范中的内容

预陈述的定义如下:

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
声明的定义如下:

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位于块中,否则LocalVariableDeclarationStatement无效。但是,由于ForStatement要求它后跟一个语句,因此必须存在括号才能使表达式有效。因此,在没有bra的循环中,任何局部变量声明都将无效ckets。

您也可以通过以下方式使其在无支架的情况下工作:

Counter counter;
    for (int i = 0; i < 50; i++)
    counter = new Counter();
计数器;
对于(int i=0;i<50;i++)
计数器=新计数器();
并不是说你有任何理由想做这样的事。
去掉括号是一个非常糟糕的主意,因为添加一条语句实际上会使控制流发生变化。

+1更清楚地说,这是因为编译器知道在第二种情况下你什么也没做,并告诉你。在第一种情况下它没有做。这不是真的。构造函数增加了一个静态计数器,所以
new counter()
有副作用,这不是一个否定的观点。有趣的是,这不起作用-不是我说它不好,而是编译器会优化掉一些明显有副作用的东西。是的……我认为这个答案不正确。编译器没有编译这个语句-会抛出一个错误。如果一个语句没有用(无操作),它将生成警告(当然,除非您将编译器设置为抛出警告)。但是,如果您查看我的答案,您将看到@Lion的语句在Java语言规范中无效,这就是编译器失败的原因。@Shakedown-抱歉,我应该说“不处理赋值”.参见JasCav的回答-规范中有一个特定的限制。JasCav是正确的。声明语句与标准命令语句不同,不能单独作为循环体(也可能不是if/else的体).1表示去掉大括号是个坏主意。与if语句相同。仅当您要将“body”与for/if放在同一行上,作为您所做工作的某种信号时,才这样做。