2017-03-07 120 views
3

当我运行下面的代码时,它给我编译时错误。循环中的局部变量声明

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开发人员做的?

+1

只是想指出的是,编译时错误是'Test.java:4:错误:没有here'允许变量声明(指着测试obj)。 – Linuslabo

回答

6

编译器很聪明,如果你ommit的{}那么OBJ对象已拟申报无理由,因为超出范围立刻

记得ommiting的{}仅仅意味着下一行会属于为范围...

你的意思是肯定的,而不是:

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

但是范围是什么? here more info

范围的封闭区域,其中一个目的是可见的,在这种情况下OBJ内部for循环中声明的对象,这意味着你可以用它在环内才起作用,这将是准备要GC一旦循环完成...

+0

是的,我的意思是......但请你详细说明你的答案..当你说范围时我没有得到 –

1

如前所述通过上面的回答你有缺少括号的for循环

{}的点:如果您删除括号,它只会读第一条指令。任何额外的行将不会被读取。如果您有超过1行的指令要执行,请使用大括号 - 否则会引发异常。

0

如果你不把括号{},循环会后,才执行一个语句。既然你在特定的行中声明了obj,之后它就不会有任何用处。所以编译器提前警告你。

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

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

现在它将正常工作,因为两个语句都属于循环,并且在循环范围内。循环完成执行后,obj将被收集垃圾。

0

注意,这并不局限于for循环。这个问题实际上是在你的榜样的声明是“局部变量声明的声明”(jls-14.4),具体的下面一行规格:

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

你举的例子可以降低到

if(true) 
    Test2 obj; 

也不能编译。

只要你添加一个块,它编译罚款:

if(true) { 
    Test2 obj; 
}