• 为什么匿名内部类只能访问其所在方法中的final类型的局部变量?
  • 蓝色妖姬 发表于 2016/3/5 11:35:00 | 分类标签: JAVA教程 匿名类 面向对象
  • 大部分时候,类被定义成一个独立的程序单元。在某些情况下,也会把一个类放在另一个类的内部定义,这个定义在其他类内部的类就被称为内部类,包含内部类的类也被称为外部类。
      

    class Outer
    {
       
    private int a;
       
    public class Inner
        {
           
    private int a;
           
    public void method(int a)
            {
                a
    ++;         //局部变量
                this.a++;      //Inner类成员变量
                Outer.this.a++; //Outer类成员变量
            }
        }
    }       

    一般做法是在Outer中写一个返回Inner类对象的方法

    public Inner getInner()
    {
    return new Inner(); }

    在其他类中使用内部类:

    Outer outer = new Outer();
    Outer.Inner inner = outer.getInner();
    //或者Outer.Inner inner = outer.new Inner();

     static内部类的使用:

    Outer.Inner inner = new Outer.Inner();

    局部内部类(一般发生在方法中定义的匿名内部类)不能访问外部类方法中的局部变量,除非变量被声明为final类型

    1. 所谓“局部内部类”就是定义在外部类成员方法内部的类,其访问同一个方法中的局部变量,局部变量必须要用final修饰。

    2. 原因是编译程序实现上的困难:内部类对象的生命周期会超过局部变量的生命周期。局部变量的生命周期:当该方法被调用时,该方法中的局部变量在栈中被创建,当方法调用结束时,退栈,这些局部变量全部死亡。而内部类对象生命周期与其它类一样:自创建一个局部内部类对象,系统为该对象分配内存起,直到没有引用变量指向分配给该对象的内存为止,它才会死亡(被JVM垃圾回收)。所以完全可能出现的一种情况是:成员方法已调用结束,局部变量已死亡,但局部内部类的对象仍然活着。

    3. 如果局部内部类的对象访问了同一个方法中的局部变量,就要求只要局部内部类对象还活着,那么栈中的那些它要所访问的局部变量就不能“死亡”。

    4. 解决方法:局部内部类对象可以访问同一个方法中被定义为final类型的局部变量。定义为final后,编译程序的实现方法:将所有的局部内部类对象要访问的final类型局部变量,都拷贝成为该内部类对象中的一个数据成员。这样,即使栈中局部变量已死亡,但被定义为final类型的局部变量的值永远不变,因而局部内部类对象在局部变量死亡后,照样可以访问final类型的局部变量,因为它自己拷贝了一份,且与原局部变量的值始终一致。

    最后,从Java 8开始这个限制被取消了,Java 8更加智能:如果局部变量被匿名内部类访问,那么该局部变量相当于自动使用了final修饰

  • 请您注意

    ·自觉遵守:爱国、守法、自律、真实、文明的原则

    ·尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法规

    ·严禁发表危害国家安全,破坏民族团结、国家宗教政策和社会稳定,含侮辱、诽谤、教唆、淫秽等内容的作品

    ·承担一切因您的行为而直接或间接导致的民事或刑事法律责任

    ·您在编程中国社区新闻评论发表的作品,本网站有权在网站内保留、转载、引用或者删除

    ·参与本评论即表明您已经阅读并接受上述条款

  • 感谢本文作者
  • 作者头像
  • 昵称:蓝色妖姬
  • 加入时间:2013/6/13 0:00:00
  • TA的签名
  • 这家伙很懒,虾米都没写
  • +进入TA的空间
  • 以下内容也很赞哦
分享按钮