zoukankan      html  css  js  c++  java
  • 内部类的原理理解

      对于内部类的概念一直理解的不是很深刻,今天下午看了一下一些大牛的博客,结合《core Java》这本书对于内部类的描写(占了一章的较大的篇幅),将知识点总结如下:

      基础知识:内部类定义在一个类的内部,可以无视私有权限的访问外部类的变量。内部类分为两种:

      1.类中内部类(私有内部类,静态内部类)

      2.方法内内部类(局部内部类,匿名内部类)

      一.类中内部类

      对于类中内部类,对于一个外部类进行编译后,会生成两个文件:1)Outer.class文件,2)Outer$Inner.class文件,内部类是一种编译器现象,与虚拟机无关,编译器会将内部类翻译成用$分割外部类名与内部类名的常规类文件,而虚拟机对此一无所知,这是其一。

      那么内部类是如何访问外部类的私有变量的呢?以下是反射得到的结果:

      

    class Outer$Inner {
        public Outer$Inner(Outer);
        final Outer this$0;
    }

      可以看出编译器会在内部类中添加一个对于外部类的引用,并且在内部类初始化的时候,将外部类的引用传入,方便调用外部类的变量。但是外部类的私有变量是如何访问的呢?这还是要看外部类的反射结果:(这里假设内部类使用了外部类的私有变量x),以下是外部类的反射结果:

    class Outer {
        private int x;
        public Outer(int);
        static int access$0(Outer);
    }

      很明显,在编译器检测到内部类需要访问外部类的私有成员变量的时候,会在外部类“动手脚”,即创建一个叫做access$0方法,它将返回作为参数传递给它的对象域x,内部类的方法将调用这个方法,即内部类访问x的时候,实际上是access$0(this$0),这就是内部类能访问外部类成员变量的原因。

      接下来讨论的是静态内部类。

      静态内部类是没有指向外部类的引用this$0的,相对应的也无法访问外部类的非静态成员,除此之外与非静态内部类没有区别。

      二.方法内部类

      对于局部内部类来说,是如何访问方法参数中的变量或者方法定义的变量呢?答案是编译器会自动添加相对应的构造参数。对于一个在方法中声明的内部类进行反射,得到的代码如下:

      

    class Outer$Inner {
        Outer$Inner(Outer,int);
        final int val$x;
        final Outer this$0;
    }

      注意构造器的int参数和val$x的实例变量。当创建一个对象的时候,x会被传入构造函数,并且最终对于val$x进行初始化,这也是局部内部类中的变量必须为final的原因,所以final关键字的目的就是为了保证内部类和外部函数对变量“认识”的一致性。

      而对于匿名内部类,其不能有构造器,因此取而代之的是将构造器参数传递给超类构造器。

    加油
  • 相关阅读:
    guake 3.4发布,支持切分窗口
    tmux下vim颜色不正常问题
    tmux下make menuconfig背景色不正常问题
    命令行工具PathMarker
    busybox syslog介绍
    linux下检测可用串口并使用minicom打开(改进版)
    linux下检测可用串口并使用minicom打开
    guake终端复制标签页
    shell命令行混合进制计算器smartbc
    在shell脚本中添加暂停,按任意键继续
  • 原文地址:https://www.cnblogs.com/hlhdidi/p/5575607.html
Copyright © 2011-2022 走看看