2012-02-05 49 views
0

我需要解释为什么下面的代码将无法编译(在范围和寿命方面):Java的范围和使用寿命(内部类)

class ClassInMethod 
{ 
    public static void main(String[] args) 
    { 
     int local = 1; 

     class Inner 
     { 
     public void method() 
     { 
      System.out.println(local); 
     } 
     } 
    } 
} 

认为这是因为: 任何局部变量使用但未在内部类中声明的内容必须声明为“最终”。因此,在本例中,'local'必须声明为final,因为它的范围和生命周期在主方法内结束(因此需要更改为:final int local = 1;)。

任何其他建议?

+1

家庭作业?你有没有试过编译它? ;) – Jonathan 2012-02-05 21:07:36

+0

它是(因此标签;);我有。但实际上,我认为我想到了 - 如果你对我的第二次尝试感兴趣,请在〜30秒内查看我的帖子! – tommy1370 2012-02-05 21:14:24

+2

这个页面可能有助于解释_why_你需要变量是最终的:http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/ – DNA 2012-02-05 21:15:57

回答

1

你必须使局部变量final的原因是Java将它们的值复制到内部类的实例中。会发生什么幕后是编译器生成(大致)对应于这个字节码:

class ClassInMethod { 
    public static void main(String[] args) { 
     int local = 1; 

     // this happens when you do: new Inner() 
     ClassInMethod_main_Inner inner = new ClassInMethod_main_Inner(); 
     inner.local = local; 
    } 
} 

// the inner class 
class ClassInMethod_main_Inner { 
    int local; 

    public void method() { 
     System.out.println(local); 
    } 
} 

如果localfinal,你可以改变它的时候Inner被实例化之间的值,当method()被称为,致电method()将使用旧值local。这可能是不正确的行为。 final的原因是让内部类的行为更直观。

(有没有这个限制的语言,但它需要编译器和运行时的明确支持。Java的开发人员到目前为止还没有决定献出自己的努力来实现它。)

1

试着编译它。编译器输出:

 
ClassInMethod.java:11: local variable local is accessed from within inner class; needs to be declared final 
    System.out.println(local); 
        ^
1 error 
+0

谢谢,我得到了那么多我只是想确定我没有错过任何东西! – tommy1370 2012-02-05 21:17:56