黑马程序员技术交流社区

标题: 关于局部内部类 [打印本页]

作者: 杨文宇    时间: 2012-7-24 17:55
标题: 关于局部内部类
本帖最后由 杨文宇 于 2012-7-24 18:42 编辑

class A
{
        int y = 3;
        public void print(){
           
           final int x = 2;//可以访问外部类的成员,但是只能访问所在函数的final局部变量。为什么只能访问所在final的局部变量?

           class LocalClass
           {
                   public int showX(){
                     return x;
                   }
                   public int showY(){
                     return y;
                   }
           }

           System.out.println("x="+new LocalClass().showX());
           System.out.println("y="+new LocalClass().showY());
        }
}
class Test
{
        public static void main(String[] args)
        {
                new A().print();
                System.out.println( );
        }
}
作者: 周玉龙    时间: 2012-7-24 18:00
首先在方法中定义一个内部类,但是它并不是方法的一部分,我们只是这样写代码,
目的是为了控制内部类的可见性,编译之后的结果,也会出现 外部类 和 内部类各自的字节码class文件,
这就说明内部类是一个独立的个体,他们就是两个类而已,他们各自都有自己的成员变量和方法。
并且方法的属性与内部类的生命周期不同。方法内的属性会被分配到内存中栈中的,
当方法调用结束的时候就会退栈,也就是说在内存中这个属性就消失了,然而这个内部类会被分配到堆内存中,
生命还在,并没有消失。如果让内部类再使用被销毁的属性这并不合理。
解决方法就是加上final关键字。在java中, 某个属性一旦加上final关键字,就 可以看作是常量,
而常量的生命周期在程序的整个执行期间都是有效的。所有这个时候的属性的生命周期变的比内部类更长了。所以可以引用, 不会出错。


作者: 王志明    时间: 2012-7-24 18:01
不是final的局部变量,你的方法结束了就没了。

但是你的内部类却不是和你的方法同时执行的,比如实现ActionListener,当你事件发生的时候才会执行,这时你的方法已经结束了,ActionListener到哪里去找这个局部变量呢?

作者: 王志明    时间: 2012-7-24 18:04
(1).所谓“局部内部类”就是在对象的方法成员内部定义的类。而方法中的类,访问同一个方法中的局部变量,却必须要加上一个final。
(2).原因是编译程序实现上的困难:内部类对象的生命周期会超过局部变量的生命期。局部变量的生命期:当该方法被调用时,该方法中的局部变量在栈中被创建,当方法调用结束时,退栈,这些局部变量全部死亡。而内部类对象生命期,与其它类一样,当创建一个局部内部类对象后,只有当没有其它人再引用它时,它才能死亡。所以完全可能一个方法已调用结束(局部变量已死亡),但该局部类的对象仍然活着。即:局部类的对象生命期会超过局部变量。
(3).局部内部类的对象访问同一个方法中的局部变量,那么这就要求只要局部内部类对象还活着,那么栈中的那些它要访问的局部变量就不能“死亡”(否则:它都死了,还访问个什么呢?)。这就是说:局部变量的生命期至少等于或大于局部内部类对象的生命期。
(4).解决方法:局部内部类的对象可以访问同一个方法中被定义为final的局部变量。定义为final后,编译程序的实现方法:将所有的局部内部类对象要访问的final型局部变量,都拷贝成为该内部类对象中的一个数据成员。这样,即使栈中局部变量(含final)已死亡,但由于它是final,其值永不变,因而局部内部类对象在变量死亡后,照样可以访问final型局部变量。(这一点我有些怀疑)
(5).归纳总结:局部内部类对象中包含有要访问的final型局部变量的一个拷贝,成为它的数据成员。因此,正是在这个意义上,final型局部变量的生命期,超过其方法的一次调用。严格来说,方法调用结束,所有的局部变量(含final)全死亡了。但:局部内部类对象中有final型局部变量的拷贝。


作者: 杨文宇    时间: 2012-7-24 18:35
周玉龙 发表于 2012-7-24 18:00
首先在方法中定义一个内部类,但是它并不是方法的一部分,我们只是这样写代码,
目的是为了控制内部类的可 ...

我懂了。感谢:handshake
作者: 周玉龙    时间: 2012-7-24 18:47
杨文宇 发表于 2012-7-24 18:35
我懂了。感谢

没事,应该的,




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2