内部类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内部类相关的知识,希望对你有一定的参考价值。

内部类

编译器会将内部类翻译成用0
(如 final [outer class] this $0)。

为了使内部类拥有访问外部类私有数据的特权,编译器会在外部类添加返回作为参数传递给它的对象的成员的静态方法。 (如access $0)
构造内部类对象时会将创建它的外部对象 this 引用传递给它。

内部类会被继承吗

不会 继承了外部类 重新声明的新内部类和原本的内部类存在不同的命名空间内,互不影响,但是可以明确的继承某个内部类

安全风险:

通过调用 access 0 不是合法方法名。
但是可以使用十六进制编辑器创建使用虚拟机指令调用方法的类文件。

使用.this和.new

在内部类中可以使用outerclassName.this获得对外部对象的引用,这个操作会在编译器完成,因此不会有运行时开销

如果想要创建某个类的内部类对象,可以使用外部类处对象引用.new来创建 如

outClass o = new outClass();
innerClass in = o.new innerClass();

内部类和接口组合可以完全隐藏实现的细节,因为private的内部类无法被外部类以外任何人访问,甚至不能向下转型为private内部类或者protected内部类 除非是继承自它的子类,因为无法访问到其名字.

局部类:

声明在方法块中,除了所在的方法,没有人会知道它的存在,可以嵌入在任意的作用域中

优势:

可以访问局部变量,内部类不行,但是局部变量需要是事实上 final


匿名内部类:

只创建一个对象,没有命名的意义
语法:

new supertype ()
{
inner class methods and data
}

没有类名,所以没有构造器,但是需要提供参数,如果继承接口不可以有参数,但是要有()。

可以通过实例初始化达到创建一个构造器的效果

public class Parcel10{
    public Destination destination(final String dest,final float price){
        return new Destination(){
            private int cost;
          {
              cost=Math.round(price);
            if(cost>100){
                System.out.println("Over bugget");
            }
          }
          private String label = dest;
          public String readLabel(){ return label; }
        }
    }
}

匿名内部类和正规类的继承相比有些首先,扩展类和继承接口只能二选一,而且继承接口不能多个.

双括号初始化

invite(new ArrayList<String>(){{add("harry");add()"tony";}});

外层括号建立了一个arrayList的匿名子类,内层括号是构造块,构造了一个数组列表传给方法。

注意

现在更推荐使用lambda表达式代替匿名内部类的使用,会更加简洁。


静态内部类

不需要内部类引用外部类对象时声明为static,可以取消产生的引用。

静态内部类可以有静态域和方法。

声明在接口中的内部类自动成为public static类





以上是关于内部类的主要内容,如果未能解决你的问题,请参考以下文章

片段 - 全局视图变量与本地和内部类侦听器和内存泄漏

为啥片段类应该是公开的?

ForegroundService没有从片段开始?

在内部片段类中使用ListView

自定义无内存泄漏的Handler内部类

底部导航 如何从片段内部更改片段