以下均出自: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的值 } }
对于以上代码相当于:
//外部类 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 */