关于局部内部类访问带有final修饰符的局部变量


以下均出自:http://ldzyz007.iteye.com/blog/844380,略有删改.

1.首先来看段代码:

 

interface Inter{
 
  public abstract void function();

}



//外部类
class Outer{
  
   public Inter method(){ //返回值类型不能采用Inner,因为内部类在局部位置上,
                          //当method加载时,还没有加载内部类(或者说还不知道有Inner)
    final int a=3;   
    //局部内部类
      class Inner implements Inter{
        
             public void function(){
              
              System.out.println("a= "+a);
    
       }
    
     } 
    return new Inner();
  }
 
}



class FinalVariable{
 
   public static void main(String[] args){
  
     Outer out=new Outer();
     Inter it=out.method();//返回内部类对象
     /*
     当以上执行完毕,此时在栈中的a(局部变量,即使是finnal)
     所占用的内存已经释放
     */
     
     
     it.function();//但是可以打印出a的值
   }


}

FinalVariable

对于以上代码相当于:

//外部类
class Outer{
  
   public Inter method(){ 

       final int a=3;   
    //局部内部类
      class Inner implements Inter{
            //
final int a=3;
//在内部类定义了一个finnal成员a,该值拷贝的是局部a的值
                           //这就是在我们主观上认为打印出的 局部变量 a,其实是内部的成员变量a
             public void function(){
              
              System.out.println("a= "+a);
    
       }
    
     } 
    return new Inner();
  }
 
}

               

看到以上,你也会在想(当然我想了O(∩_∩)O哈哈~),可不可以规定非final的局部变量也像final变量那样拷贝一下作为局部内部类成员变量,那不也可以访问了吗?

这时候就用到final变量的特性了.我把以上代码简单修改下:

 

class Outer{
  
   public void method(){ 
      int a=3;   
    //局部内部类
      class Inner implements Inter{
            // int a=3;
             public void function(){
              
              ++a;
             
    
         }
    
     } 
    new Inner().function();//此时a会自增 
    System.out.println(a);//3
  }
 
}
/*
假设我规定 非final变量,也会拷贝到局部内部类中,那么
以上可以执行成功的,那么输出结果为3,并不是4
这是因为打印的是 局部变量a 而并非 成员变量a
++a改变的是成员变量a
这样就造成误解,我们主观意愿是通过内部类方法改变下局部变量a
在输出,但结果没变.

因此为了保证一致性,规定局部内部类只能访问final局部变量(它具有一经初始化,不允许改变的特性)
保证了 我们主观意愿上 使用的是同一个a
*/
posted @ 2013-04-02 17:54  伊秋  阅读(321)  评论(0编辑  收藏  举报