众所周知,局部内部类访问局部变量,需要在局部变量前面加上final修饰符,关于这个问题的解答,包括各种书籍里面都有不同的答案.
但是,今天在石松老师的讲解并演示下,我彻底明白了,只有一个原因,那就是:生命周期的原因.
class Outerx{
public void show(){
int x=6;
class Inner{
public void function(){
System.out.println("hei"+x);
}
}
new Inner().function();
}
}
此时如果编译的话,会提示:从内部类中访问本地变量x,需要被声明为最终类型.
如果加上最终类型,final 后 final int x = 6; 再次进行编译,则会成功输出内容.
那么问题来了,为什么加上一个final后,就会成功运行了呢?就像我前面说的,生命周期.....可是有的书上也写道,
是延长了变量的生命周期,对于这样的话,我想说:明显是不正确的.
可以做个小实验,比如在main方法里面写:
public static void main(String[]ag){
{
final int x = 100;
}
System.out.println(x);
}
此时如果编译的话,会提示:找不到符号 ,出去了范围以后,就不能再使用了,此处说final延长了生命周期,明显已经站不住脚了.
而解决这个问题,可以换一个思路,也许只是绕过了这个棘手的问题呢?
也就是说:加上了final以后,x的值固定为了6,Java编译的时候,后面访问x的地方,直接写成了6,就不让x再出现了.
话虽如此,也要验证一下,比如,可以反编译一下,就可以清楚的看到class文件里面虽然有一堆乱码,但是乱码中间有这样几个词还是可以认得的
hei!6
在局部内部类和局部变量是同样的级别,因此,不存在超出范围,也就是找不到符号的前提下,sun公司巧妙的规避了这样的一个问题,通过final关键字,让输出语句内的变量变成了常量固定的值. |