循环中的局部变量声明

Local variable declaration in loop

当我运行下面的代码时,它给我编译时错误。

public class Test {
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++)
       Test2 obj = new Test2();// Compile time error- Multiple markers at this line
        System.out.println(Test2.numCreated());
    }
}

class Test2 {
    private static long number= 0;


    public static long numCreated() {
        return number;
    }
}

但是当我将局部变量声明语句 Test2 obj= new Test2() 直接放在块中时,一切正常。

有人可以向我解释这背后的原因或者 Java 开发人员这样做的原因吗?

编译器非常聪明,如果你省略 { } 那么 obj 对象就没有理由被声明了,因为它已经出来了范围立即

记住省略 { } 意味着只有下一行将属于 for 范围...

你的意思是:

for (int i = 0; i < 100; i++){
      Test2 obj = new Test2();
}

但是范围是什么? here more info

scope 是对象可见的封闭区域,在这种情况下,对象 obj 是在 for 循环内声明的,这意味着您只能在循环内使用它一旦循环完成,它将准备好成为 GC...

正如上面的回答所述,你明白了缺少 for 循环

的大括号 {}

注意:如果去掉大括号,它只会读取指令的第一行。不会读取任何额外的行。如果要执行的指令多于 1 行,请使用花括号 - 否则将抛出异常。

如果不放大括号{ },循环只会执行它后面的一条语句。由于您在该特定行中声明了 obj ,因此之后它不会有任何用处。所以编译器会提前警告你。

如果要执行多个语句并使用变量,则必须使用 { }

for (int i = 0; i < 100; i++){
       Test2 obj = new Test2();
       System.out.println(Test2.numCreated());
}

现在它可以正常工作了,因为这两个语句都属于循环并且在循环的范围内。循环执行完毕后,obj将被垃圾回收。

请注意,这不限于 for 循环。问题实际上是您的示例中的语句是 "Local Variable Declaration Statement" (jls-14.4),特别是规范中的以下行:

Every local variable declaration statement is immediately contained by a block.

你的例子可以简化为

if(true)
    Test2 obj;

这也不编译。

只要你添加一个块,它就可以正常编译:

if(true) {
    Test2 obj;
}